home *** CD-ROM | disk | FTP | other *** search
- **MFM TRACK LOADER (V1.6)
- **EARLY VERSIONS CODED BY NEGATIVE ACTION OF KILLERS !
- **NOW ++OMICRON++ OF WIZZCAT !
- ** ASSEMBLED USING DEVPAC2.14
-
- **PUT ONTO BOOTBLOCK USING UTIL. SUCH AS BOOTWRITER
-
- **CALL PARAMETERS :- (TRAP #1 TO ACTIVATE !)
-
- ** D0=START CYLINDER
- ** D1=NUMBER OF CYLINDERS
- ** D2=MFM BUFFER (RESERVE $5000 BYTES !)
- ** A0=DESTINATION ADDRESS
-
- ** INITIAL PARAMETERS :-
- ** MFMD=INITAL MFM BUFFER ADDRESS
- ** SYSBASE=LOADER BASE ADDRESS/STACK ADDRESS (SUGGESTED =<$1000)
- ** INITIALLOAD=ADDRESS TO LOAD INITIAL DATA + INITIAL JUMP
- ** STARTCYL/NUMCYL=START CYLINDER+NUMBER TO LOAD
- ** ISR=INITAL STATUS REGISTER
-
- section loader2,code_c
- opt c-,d-
-
- time=2148 a bit more than 3 milliseconds !
- mfmd=$7b000 Set buffer to $7b000
- sysbase=$400 $400 for stack+loader code (+TRAP1)
- initialload=$1000 Initial load+jump address
- startcyl=62 Start cylinder
- numcyl=8 Number of cylinders to load
- ISR=$2000 Supervisor + Enable all Ints.
-
-
- intreqr EQU $01E
- dskpt EQU $020
- dsklen EQU $024
- dsksync EQU $07E
- dmacon EQU $096
- intena EQU $09A
- intreq EQU $09C
- adkcon EQU $09E
- bplcon0 EQU $100
- color EQU $180
-
- **BOOT STUFF !!
- dc.b "DOS",0
- ds.l 1
- dc.l $370
-
- bootstart
- lea bootem(pc),a0
- move.l a0,$20.w
- bootem move.w #ISR,sr
- bsr loadreg
- move.w #$7fff,d0
- move.w d0,intena-$24(a5)
- move.w d0,dmacon-$24(a5) no ints. or dma
- move.w d0,adkcon-$24(a5) clear disk control !!
- move.b #$08,$e00(a3) one-shot mode
- move.w #$9500,adkcon-$24(a5) set prefs for disk
- move.w #$4489,dsksync-$24(a5) standard sync
- bset #1,(a3) set LED
-
- bsr activatedrive
- .loop1 btst #4,(a3) track 0 ?
- beq.s setupdma
- bsr headsout step heads out
- bra.s .loop1
- setupdma
- moveq #0,d1
- move.w d1,bplcon0-$24(a5) no colors !!
- lea $140-$24(a5),a0
- moveq #16,d0
- .nosprt move.l d1,(a0)+
- dbra d0,.nosprt clear sprites & color0 !!
-
- lea mainloader(pc),a0
- lea sysbase,a1 loader base address
- move.l a1,$84.w
- move.l a1,a7
- moveq #(loaderend-mainloader)/4,d0
- .copydown
- move.l (a0)+,(a1)+ copy
- dbra d0,.copydown
-
- lea startloader(pc),a0
- move.l a1,a2
- moveq #mainloader-startloader-1,d0 not to overwrite !
- .copyinit
- move.b (a0)+,(a1)+
- dbra d0,.copyinit
- jmp (a2)
-
- startloader
- lea initialload,a0 load address
- moveq #startcyl,d0 start cylinder
- moveq #numcyl,d1 number of cylinders
- move.l #mfmd,d2 mfm address !
- trap #1 load tracks
- jmp (a0) into progy !!
-
- mainloader
- movem.l d0-d7/a0-a6,-(sp) save all regs.
- bsr loadreg load my regs.
- movem.l d2/a0,mfm(a4) mfm maddress + dest address !
-
- bsr.s activatedrive
-
- bsr step step heads to cylinder
- bsr.s readendecode read cylinders + decode 'em
- bsr.s drivesoff
-
- movem.l (sp)+,d0-d7/a0-a6
- rte return
-
- drivesoff
- move.b #$f9,(a6)
- move.b #$f1,(a6)
- rts
-
- activatedrive
- move.b #$79,(a6) all drive bits on high !!
- move.b #$71,(a6)
- bsr waitdrive
- rts
-
- readendecode
- bset #2,(a6) read head 0 !
- bsr.s loaderror
- .error1 bsr.s checkerror
- bsr.s read
- bsr.s decode
- bne.s .error1
- bclr #2,(a6) read head 1 !
- bsr.s loaderror
- .error2 bsr.s checkerror
- bsr.s read
- bsr.s decode
- bne.s .error2
-
- cmp.w #79,(a4) are we on track 79 !!
- beq.s exitl yes then exit !!
- addq.w #1,(a4) add 1 to track !
-
- bsr headin
- subq.w #1,d0 tracks to read
- bne.s readendecode
- exitl rts
- loaderror
- move.w #11,error(a4)
- rts
-
- checkerror
- subq.w #1,error(a4)
- bne.s exitl
- bsr.s drivesoff
- moveq #-1,d0
- .loop move.w d0,$180-$24(a5)
- dbra d0,.loop
- .hold bra.s .hold
-
- read
- move.w #$8210,dmacon-$24(a5) enable disk dma
- move.l mfm(a4),dskpt-$24(a5) destination
- move.w #$4000,d6
- move.w d6,(a5)
- move.w #$9900,d3
- move.w d3,(a5)
- move.w d3,(a5) read 7000 mfm words
- moveq #$2,d7
- move.w d7,intreq-$24(a5) clear DISK BLOCK DONE interupt request
- .waitblock
- move.w intreqr-$24(a5),d1
- and.w d7,d1
- beq.s .waitblock test for DISK BLOCK DONE,wait till read
- move.w d6,(a5) no more dma
- move.w #$10,dmacon-$24(a5)
- rts
-
- decode
- move.l #$55555555,d3 mask off in d3
- move.l mfm(a4),a0
- lea $4f00(a0),a1 store track table address !
- move.l a1,-(sp)
- move.w #$4489,d6 standard sync !!
- moveq #10,d7 11 sectors
-
- .loop0 cmp.w (a0)+,d6
- bne.s .loop0
- cmp.w (a0),d6 2nd sync ?
- beq.s .loop0 found branch
- .loop2 move.l a0,a2
- movem.l (a0),d1-d2 info part
- and.l d3,D1
- and.l d3,d2
- add.l d1,d1
- or.l d2,d1 decode block info
- lsr.w #8,d1
- move.w d1,(a1)+ save sector
- lea 44(a0),a0 block checksum
- move.l (a0)+,d5 block checksum in d5
-
- moveq #9,d1 byte count
- .bc move.l (a2)+,d4
- eor.l d4,d5 eor with checksum
- dbra d1,.bc calculate header checksum
- and.l d3,d5 mask clock bits
- bne.s loadreg return on error
-
- addq.l #4,a0 align for data checksum
- move.l (a0)+,(a1)+ data checksum !!
- move.l a0,(a1)+ and address of data
- lea 1024(a0),a0 next sector
- dbra d7,.loop0 for all tracks
-
- move.l current(a4),a1 address of decoded data
- move.l (sp)+,a0 restore track table !
- moveq #$A,d7 11 sectors
- .loop3 move.w (a0)+,d1 sector
- moveq #9,d2
- lsl.w d2,d1 multiply by 512
- lea 0(a1,d1.w),a3 multiply by 1 sector and save address
-
- movem.l (a0)+,d2/a2 checksum + start of data
- lea 512(a2),a5 next set of datas
- moveq #512/4-1,d4
- .dcode move.l (a2)+,d5 data
- move.l (a5)+,d6 data
- eor.l d6,d2
- eor.l d5,d2 fix data checksum !!
-
- and.l d3,d5
- and.l d3,d6
- add.l d5,d5
- or.l d6,d5
- move.l d5,(a3)+ save data
- dbra d4,.dcode continue
- and.l d3,d2 mask checksum
- bne.s loadreg if sum is ok then branch
- .sumok dbra d7,.loop3
- add.l #512*11,current(a4)
- bsr.s loadreg
- moveq #0,d7 clear error
- rts
-
- loadreg
- lea $bfe001.l,a3
- lea data(pc),a4
- lea -$f01(a3),a6
- lea $dff024.l,a5
- rts
-
-
- step move.w (a4),d2 current track
- exg d0,d1 swap !
- move.w d1,(a4) start track
- sub.w d2,d1 subtract to get number of tracks to skip
- bmi.s headout step heads out if difference is negative
- beq.s .ret1 0, then there already
- .loop0 bsr.s headin step heads in
- subq.w #1,d1
- bne.s .loop0
- .ret1 rts
-
- headout
- .loop0 bsr.s headsout
- addq.w #1,d1 for loop
- bne.s .loop0
- rts
-
- waitdrive
- .loop0 btst #5,(a3)
- bne.s .loop0 drive ready ?, no wait
- rts
-
- headin
- bclr #1,(a6)
- bra.s stepit
- headsout
- bset #1,(a6)
- stepit
- moveq #0,d6
- bclr d6,(a6)
- bset d6,(a6)
- move.b #$7f,$d00(a3)
- move.b #time&$ff,$400(a3)
- move.b #time>>8,$500(a3) set timer lo/hi & start timer
- .busy btst d6,$d00(a3) wait for timer interupt
- beq.s .busy busy then back !
- rts
-
- rsreset
- track rs.w 1
- mfm rs.l 1
- current rs.l 1
- error rs.w 1
-
- data ds.w 1
- loaderend
- end
-