**--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** ** Direct Disk Access File Loader By Nova. ** Set tabs to 10 **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** Restore equ 0 Seek equ 1 Step equ 2 Stepin equ 3 Stepout equ 4 Readsect equ 5 Writesect equ 6 Readtrk equ 7 Writetrk equ 8 DriveA equ 0 DriveB equ 1 Side0 equ 0 Side1 equ 1 pstart move.l sp,oldusp pea stack move #$20,-(sp) trap #1 move.l d0,oldssp move #1,$43e.w moveq #0,d0 bsr restore bsr initdisc get disc format info lea file,a0 get file size/1st cluster bsr getfinfo tst.l d0 bmi.s .notfound move.l #1024,d2 bsr seek lea filespace,a0 where to load bsr loadfile .notfound moveq #1,d0 bsr restore move #0,$43e.w move.l oldssp,-(sp) move #$20,-(sp) trap #1 move.l oldusp,sp clr -(sp) trap #1 **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** ** Subroutines **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** restore move.l d0,-(sp) move #Restore,command moveq #DriveA,d1 moveq #Side0,d2 bsr startcom move #0,track bsr waitend move.l (sp)+,d0 tst.l d0 beq .nwo bsr motoroff .nwo rts **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** ** d0=file lenght ,truncated to lenght left ** d1=start cluster ,set to first cluster to read ** d2=bytes to seek by ,set to offset for load file routine seek lea LogFat,a0 sub.l d2,d0 bmi.s .error .seek cmp.l #1024,d2 blt .ok sub.l #1024,d2 decrement seek value lsl #1,d1 goto next cluster move (a0,d1),d1 bra.s .seek .ok rts .error moveq #-1,d0 rts **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** ** d0=bytes to load ** d1=starting cluster ** d2=offset from start of cluster to load from ( must be even ) ** a0=where to load loadfile move.l d0,size move d1,cluster and.l #$03FE,d2 move d2,offset move.l a0,loadadd bsr conclust tst offset beq .loadclusters move sct,d0 move trk,d1 move side_,d2 move #DriveA,d3 moveq #2,d7 lea Cluster,a0 bsr readsectors bsr copypart bsr nxtcluster .loadclusters cmp.l #1024,size blt .lastbit bsr conclust .clu_loop move sct,sector get info on sector to read move trk,d1 move side_,d2 moveq #DriveA,d3 bsr loadncon cmp.l #1024,size bge .clu_loop .lastbit tst.l size beq .finload bmi .finload move sct,d0 get info on sector to read move trk,d1 move side_,d2 move #DriveA,d3 moveq #2,d7 lea Cluster,a0 bsr readsectors move #0,offset bsr copyend .finload rts ***---*** copyend lea Cluster,a0 move.l loadadd,a1 move.l size,d0 move.b d0,d1 and #1,d1 lsr #1,d0 subq #1,d0 bmi.s .isodd .cend move (a0)+,(a1)+ dbf d0,.cend .isodd tst d1 beq .done move.b (a0)+,(a1)+ .done rts ***---*** loadncon movem.l d0-3,-(sp) cmp track,d1 check if track moved beq .read bsr .movetrack .read move #Readsect,command start read op move.l loadadd,transadd movem d1-2,-(sp) move d3,d1 bsr startcom movem (sp)+,d1-2 movem.l (sp)+,d0-3 bsr nxtcluster find next cluster bsr conclust convert cluster to phy sector add.l #512,loadadd move load address sub.l #1024,size decrease size left bsr waitend move sector,d0 addq #1,d0 cmp Sectors_Track,d0 ble .notover move #1,d0 addq #1,d2 cmp Number_Sides,d2 ble .notover move #0,d2 addq #1,d1 .notover move d0,sector cmp track,d1 check if track moved beq .read2 bsr .movetrack .read2 move #Readsect,command start read op move.l loadadd,transadd movem d1-2,-(sp) move d3,d1 bsr startcom movem (sp)+,d1-2 add.l #512,loadadd bsr waitend rts ***---*** .movetrack movem d1-2,-(sp) move d1,track move #Seek,command move d3,d1 bsr startcom bsr waitend movem (sp)+,d1-2 rts ***---*** conclust movem.l d0-3,-(sp) move cluster,d0 bsr cluster2log bsr log2phy move d0,sct move d1,trk move d2,side_ movem.l (sp)+,d0-3 rts ***---*** nxtcluster movem.l d0/a0,-(sp) move cluster,d0 lea LogFat,a0 lsl #1,d0 move (a0,d0),d0 move d0,cluster movem.l (sp)+,d0/a0 rts ***---*** copypart lea Cluster,a0 add offset,a0 move.l loadadd,a1 move.l #1024,d0 sub offset,d0 bmi.s .copysmall sub.l d0,size lsr #1,d0 subq #1,d0 .copy2 move (a0)+,(a1)+ dbf d0,.copy2 move.l a1,loadadd rts .copysmall move.l size,d0 .copy subq #2,d0 bmi.s .fin1 move (a0)+,(a1)+ bra.s .copy .fin1 move.l a1,loadadd move.l #0,size rts ***---*** sct dc.w 0 trk dc.w 0 side_ dc.w 0 cluster dc.w 0 size dc.l 0 offset dc.w 0 loadadd dc.l 0 **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** ** this routine gets the lenght and attribute of the file in a0 ** and the starting cluster in d2 ** a0=file name ** d0=file lenght ** d1=first cluster ** d2=file attribute getfinfo bsr logname2phyname convert file name to disc format bsr findindir find name in the directory tst.l d0 bmi.s .nfound moveq #0,d0 get file size move.b 31(a0),d0 rol.l #8,d0 move.b 30(a0),d0 rol.l #8,d0 move.b 29(a0),d0 rol.l #8,d0 move.b 28(a0),d0 moveq #0,d2 get file attribute move.b 11(a0),d2 moveq #0,d1 get first cluster move.b 27(a0),d1 rol.l #8,d1 move.b 26(a0),d1 .nfound rts **--**--**--**--**--** ** finds file in phyname in the directory ** a0=pointer to filename in directory ** d0=0 if file found -1 if not found findindir movem.l d1-3/a1-3,-(sp) moveq #-1,d0 lea RootDirectory,a0 lea phyname,a1 .entry move.l a0,a2 move.l a1,a3 moveq #10,d3 .check move.b (a2)+,d1 move.b (a3)+,d2 cmp.b d1,d2 bne.s .nxt dbf d3,.check moveq #0,d0 movem.l (sp)+,d1-3/a1-3 rts .nxt lea 32(a0),a0 tst.l (a0) if entry is 0 then no more entrys beq .end bra .entry .end movem.l (sp)+,d1-3/a1-3 rts **--**--**--**--**--** ** a0=name to convert to disc format name logname2phyname movem.l d0/a0-1,-(sp) lea phyname,a1 move.l #' ',(a1) clear the name move.l #' ',4(a1) move.l #' ',8(a1) .convert move.b (a0)+,d0 get byte tst.b d0 if zero we've done beq .done cmp.b #'.',d0 test for '.' beq.s .pad if so pad it out move.b d0,(a1)+ bra.s .convert .pad lea phyname+8,a1 .doext move.b (a0)+,d0 tst.b d0 beq.s .done move.b d0,(a1)+ bra.s .doext .done movem.l (sp)+,d0/a0-1 rts **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** ** this subroutine get the format info of drive A and gets the fat and ** directory. initdisc bsr restore bsr getBOOT bsr getformatinfo bsr getFAT bsr decodefat bsr getDIR moveq #0,d0 rts badformatt moveq #-1,d0 rts getBOOT moveq #1,d0 moveq #0,d1 moveq #Side0,d2 moveq #DriveA,d3 moveq #1,d4 lea Sector,a0 bsr readsector rts getFAT moveq #2,d0 read all Fat table moveq #0,d1 at track zero moveq #0,d2 side zero moveq #3,d7 lea RootDirectory,a0 load fat into directory bsr readsectors space rts getDIR move #1,d0 calculate log sect of dir move Sectors_Fat,d1 move Number_Fats,d2 mulu d2,d1 add d1,d0 bsr log2phy moveq #0,d3 drive a moveq #1,d4 leave drive on lea RootDirectory,a0 move Sectors_Root,d7 cmp #7,d7 bgt badformatt bsr readsectors read all root directory rts **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** decodefat lea RootDirectory,a0 lea LogFat,a1 move #900-1,d7 max fat entrys .decode moveq #0,d0 moveq #0,d1 moveq #0,d2 move.b (a0)+,d1 get 8 highest bits of lo entry move.b (a0)+,d2 store byte to be split move.b (a0)+,d0 get 8 highest bits of hi entry lsl #4,d0 move bits move.b d2,d3 make copy lsr #4,d2 get lo 4 bits of hi entry or d2,d0 put lo bits in hi entry and #15,d3 get high bits of lo entry rol #8,d1 shift lo bits move.b d3,d1 set high bits rol #8,d1 correct entry move d1,(a1)+ store decoded entrys move d0,(a1)+ dbf d7,.decode rts **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** getformatinfo lea Sector,a0 moveq #0,d0 move.b 16(a0),d0 move d0,Number_Fats move.b 17(a0),Max_Dir_Entrys+1 Words are stored backwards move.b 18(a0),Max_Dir_Entrys move.b 19(a0),Total_Sectors+1 move.b 20(a0),Total_Sectors move.b 22(a0),Sectors_Fat+1 move.b 23(a0),Sectors_Fat move.b 24(a0),Sectors_Track+1 move.b 25(a0),Sectors_Track move.b 26(a0),Number_Sides+1 move.b 27(a0),Number_Sides move Max_Dir_Entrys,d0 lsr #4,d0 move d0,Sectors_Root moveq #0,d0 move Total_Sectors,d0 moveq #0,d1 move Sectors_Track,d1 divu d1,d0 move Number_Sides,d1 divu d1,d0 move d0,Number_Tracks rts **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** ** d0 = cluster number ** d0 = logical sector that cluster starts at, on return cluster2log movem.l d1-2,-(sp) subq #2,d0 -2 'cause clusters 1+2 don't exist lsl #1,d0 *2 for 2 sectors per cluster addq #1,d0 add 1 sector for boot sector move Sectors_Fat,d1 move Number_Fats,d2 mulu d2,d1 number of sectors for fats add d1,d0 add Sectors_Root,d0 add root directory on movem.l (sp)+,d1-2 rts **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** ** d0 = logical sector ** d0 = physical sector ** d1 = physical track ** d2 = side log2phy moveq #0,d2 moveq #0,d3 move Sectors_Track,d2 work out sectors per track move Number_Sides,d3 with two sides mulu d3,d2 move d0,d3 divide log sector by sct/trk and.l #$FFF,d3 divu d2,d3 move d3,d1 got physical track swap d3 remainder = sector of phy trk cmp Sectors_Track,d3 bge.s .side2 clr d2 move d3,d0 addq #1,d0 not counting from zero for phy sector rts .side2 move #1,d2 sub Sectors_Track,d3 move d3,d0 addq #1,d0 rts **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** ** d0=sector number ** d1=track ** d2=side ** d3=drive ** d7=number of sectors to read ** a0=where to read/write readsectors subq #1,d7 bmi.s .lasttrack .readem movem.l d0-3/a0,-(sp) bsr readsector movem.l (sp)+,d0-3/a0 lea $200(a0),a0 addq #1,d0 cmp Sectors_Track,d0 ble .notover moveq #1,d0 addq #1,d2 cmp Number_Sides,d2 ble .notover move #0,d2 addq #1,d1 cmp Number_Tracks,d1 beq .lasttrack .notover dbf d7,.readem moveq #0,d0 rts .lasttrack moveq #-1,d0 rts **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** ** d0=sector number ** d1=track ** d2=side ** d3=drive ** a0=where to read/write readsector move.l a0,transadd move d0,sector cmp track,d1 beq .read move d1,track move #Seek,command movem.l d0-3,-(sp) move d3,d1 bsr startcom bsr waitend movem.l (sp)+,d0-3 .read move #Readsect,command move d3,d1 bsr startcom bsr waitend rts **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** ** d0=command to do ** d1=drive ** d2=side startcom bsr Select_Drive bsr FDCaccess rts waitend move.l #2000000,d6 gives approx. 4 secounds .wfeoc subq.l #1,d6 beq .timedout nop nop btst #5,$FFFFFA01.w bne.s .wfeoc clr.l d6 rts .timedout moveq #-1,d6 rts motoroff move #$180,$FFFF8606.w select status reg .motson move $FFFF8604.w,d0 tst.b d0 bmi.s .motson move d0,stat moveq #-1,d1 moveq #0,d2 bsr Select_Drive rts Select_Drive eor #1,d2 flip side tst d1 bmi .nodrive beq .driveA move #%0010,d1 bra .setd .driveA move #%0100,d1 bra .setd .nodrive move #%0110,d1 .setd or d2,d1 move.b #14,$FFFF8800.w move.b d1,$FFFF8802.w rts **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** FDCaccess move.l d0,-(sp) move command,d0 cmp #8,d0 bgt .notvalid lsl #2,d0 jsr jtab(pc,d0.w) .notvalid move.l (sp)+,d0 rts jtab bra _restore 0 bra _seek 1 bra _step 2 bra _stepin 3 bra _stepout 4 bra _readsect 5 bra _writesect 6 bra _readtrk 7 bra _writetrk 8 _restore move #$80,$FFFF8606.w move #$01,$FFFF8604.w rts _seek move #$86,$FFFF8606.w move track,$FFFF8604.w move $FFFF8606.w,stat move #$80,$FFFF8606.w move #$11,$FFFF8604.w rts _step move #$80,$FFFF8606.w move #$31,$FFFF8604.w _stepin move #$80,$FFFF8606.w move #$51,$FFFF8604.w rts _stepout move #$80,$FFFF8606.w move #$71,$FFFF8604.w rts _readsect move #$84,$FFFF8606.w move sector,$FFFF8604.w bsr _writeaddress move #$90,$FFFF8606.w move #$190,$FFFF8606.w move #$90,$FFFF8606.w move #1,$FFFF8604.w move #$80,$FFFF8606 move #$80,$FFFF8604 rts _writesect move #$84,$FFFF8606.w set as read sector as it move sector,$FFFF8604.w doesn't work bsr _writeaddress move #$90,$FFFF8606.w move #$190,$FFFF8606.w move #$90,$FFFF8606.w move #1,$FFFF8604.w move #$80,$FFFF8606.w move #$80,$FFFF8604.w rts _readtrk bsr _writeaddress move #$90,$FFFF8606.w move #$190,$FFFF8606.w move #$90,$FFFF8606.w move #13,$FFFF8604.w move #$80,$FFFF8606.w move #$E0,$FFFF8604.w rts _writetrk bsr _writeaddress move #$190,$FFFF8606.w move #$90,$FFFF8606.w move #$190,$FFFF8606.w move #13,$FFFF8604.w move #$180,$FFFF8606.w move #$F0,$FFFF8604.w rts _writeaddress move.b transadd+3,$FFFF860d.w move.b transadd+2,$FFFF860b.w move.b transadd+1,$FFFF8609.w rts command dc.w 0 command to do sector dc.w 0 start sector track dc.w 0 side dc.w 0 drive dc.w 0 transadd dc.l 0 where to read/write data from stat dc.w 0 status of FDC **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** installFDCrout move.l $11C.w,oldFDC save old vector move.l #FDCaccess,$11C.w set mine or.b #$80,$FFFFFA09.w enable FDC on MFP or.b #$80,$FFFFFA15.w and.b #$7F,$FFFFFA11.w ensure ISR bit is clear move #1,$43E.w rts **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** removeFDCrout or.b #$80,$FFFFFA11.w ensure ISR bit is set and.b #$7F,$FFFFFA09.w disable FDC on MFP and.b #$7F,$FFFFFA15.w move.l oldFDC,$11C.w move #0,$43E.w rts **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** Section Data **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** file dc.b 'FLOAD.S',0 even **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** Section Bss **--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--++--** oldusp ds.l 1 oldssp ds.l 1 oldFDC ds.l 1 ds.l 128 stack ds.l 2 phyname ds.b 12 store name in disc format Sectors_Track ds.w 1 sectors per track Number_Tracks ds.w 1 number of tracks Total_Sectors ds.w 1 total sectors on disc Number_Sides ds.w 1 single or double sided Number_Fats ds.w 1 How many fats there are Sectors_Fat ds.w 1 sectors per fat Sectors_Root ds.w 1 calculated from Max_Dir_Entrys Max_Dir_Entrys ds.w 1 number of root directory entrys LogFat ds.w 900 Decoded Fat ( 16 bits/entry ) Cluster ds.b 512 Sector ds.b 512 RootDirectory ds.b 512*7 space for root directory filespace ds.b 20000