NEW AUTO 3,1 .LIST OFF .OP 65C02 .OR $2000 .TF lib/libblkdev *-------------------------------------- .INB INC/MACROS.I .INB INC/A2OSX.I .INB INC/MLI.I .INB INC/MLI.E.I .INB INC/IO.D2.I *-------------------------------------- * 300rpm = 5rps = 200000us / 4ms = 50000 bits MAX *-------------------------------------- TRACK16.LEN .EQ 6400 *-------------------------------------- TRACK16.GAP1 .EQ 64 640 bits * 16 * ( *Address field = D5AA96 + 4x2 + DEAAEB = 14 112 bits TRACK16.GAP2 .EQ 6 60 bits *Data field = D5AAAD + 342 + CS + DEAAEB = 349 2792 bits TRACK16.GAP3 .EQ 17 170 bits * ) * 64 + 16 * (14 + 6 + 349 + 17) = 6240 50784 bits (6348) *-------------------------------------- TRACK9.LEN .EQ 6511 *-------------------------------------- TRACK9.GAP1 .EQ 8+14 220 bits * 9 * ( *Address field = D5AA96 + 4x2 + DEAAEB = 14 112 bits TRACK9.GAP2 .EQ 5 50 bits *Data field = D5AAAD + 342 + 342 + CS = 688 5504 bits TRACK9.GAP3 .EQ 14 140 bits * ) * 9 * (14 + 5 + 688) = 6363 50904 bits (1480 free = 148 sync bytes) * 22 + 9 * (14 + 5 + 688 + 14) = 6511 52384 bits (6548) *-------------------------------------- ZPPtr1 .EQ ZPLIB ZPPtr2 .EQ ZPLIB+2 ZPPtr3 .EQ ZPLIB+4 ZPPtr4 .EQ ZPLIB+6 *-------------------------------------- * File Header (16 Bytes) *-------------------------------------- CS.START cld jmp (.1,x) .DA #$61 6502,Level 1 (65c02) .DA #1 BIN Layout Version 1 .DA 0 .DA CS.END-CS.START .DA 0 .DA 0 .DA 0 *-------------------------------------- * Relocation Table *-------------------------------------- .1 .DA LIB.LOAD .DA LIB.UNLOAD .DA GetProDOSCatSize .DA BuildProDOSCat .DA D2MotorControl .DA D2MoveHead .DA D2TrkRead16s .DA D2TrkWrite16s .DA D2TrkReadNIB .DA D2TrkWriteNIB L.TrkWriter .DA TrkWriter L.ProDOS.Boot .DA ProDOS.Boot .DA 0 *-------------------------------------- LIB.LOAD LIB.UNLOAD clc rts */-------------------------------------- * # GetProDOSCatSize * Compute space needed for ProDOS Catalog * ## C * int getprodoscatsize (short int options, short int catsize, int devsize ); * ## ASM * **In:** * PUSHW = DevSize (in 512b blocks) * PUSHB = Catalog Size (in blocks) * PUSHB = Options * ## RETURN VALUE * X=BlockCount (max 22) * Y,A=BufSize (max $4400) *\-------------------------------------- GetProDOSCatSize >PULLB VolDirHdr.Options >PULLB VolDirHdr.CatSize >PULLW VolDirHdr.TB GetProDOSCatSize.I lda VolDirHdr.TB Get DevSizeLo clc for now, no partial bitmap blk to add tay DevSize is xxxxxxxx00000000 ? beq .1 sec .1 lda VolDirHdr.TB+1 Get DevSizeHI bit #$0f DevSize is xxxx000000000000 ? beq .2 sec .2 php lsr lsr lsr lsr plp inc +1 (ProDOS) inc +1 (SOS) adc VolDirHdr.CatSize +x (VolDir) tax X = Total blocks needed for header (used) asl A = Total pages needed to build catalog. rts */-------------------------------------- * # BuildProDOSCat * **In:** * PUSHW = DevSize (in 512b blocks) * PUSHB = Catalog Size (in blocks) * PUSHB = Options * PUSHW = VolName (PSTR) * PUSHW = DstBuf (Zero filled) * Blk0 : ProDOS.BootBlk * Blk1 : SOS.BootBlk * Blk2...n : Volume Directory * Blkn+1.. : Volume Bitmap (4096/Blk) * max devSize = 65535 -> max 16 Bitmap Blk * absolute MAX DstBuf size= * 7 for Disk II(280blk),3.5(1600),3.5HD(2880) * 22 for 32mb Hardisk... *\-------------------------------------- BuildProDOSCat >PULLW ZPPtr1 DstBuf >PULLW ZPPtr2 VolName >PULLB VolDirHdr.Options >PULLB VolDirHdr.CatSize inc inc sta VolDirHdr.BMPtr >PULLW VolDirHdr.TB ldx #3 .1 lda DATELO,x sta VolDirHdr.CT,x dex bpl .1 * Blk 0 : ProDOS Boot Code >LDYA L.ProDOS.Boot >STYA ZPPtr3 ldy #0 ldx #2 2 pages .2 lda (ZPPtr3),y sta (ZPPtr1),y iny bne .2 inc ZPPtr3+1 inc ZPPtr1+1 dex bne .2 * Blk 1 : (SOS boot code) inc ZPPtr1+1 inc ZPPtr1+1 * Blk 2 : First Directory Block * ldy #0 stz VolDirHdr.Prev * stz VolDirHdr.Prev+1 always 0 lda #3 next block ldx VolDirHdr.CatSize dex bne .30 txa .30 sta VolDirHdr.next * stz VolDirHdr.next+1 * stz VolDirHdr.VER * stz VolDirHdr.MVER .3 lda (ZPPtr2),y beq .39 iny cmp #'a' bcc .38 cmp #'z'+1 bcs .38 eor #$20 pha lda LC.BitMap,y cpy #8 bcs .31 tsb VolDirHdr.VER bra .32 .31 tsb VolDirHdr.MVER .32 lda #$80 tsb VolDirHdr.VER pla .38 sta VolDirHdr.Name,y cpy #15 bne .3 .39 tya * and #$0f make sure 15 bytes max ora #$F0 Volume Directory Header sta VolDirHdr.Name ldy #VolDirHdr.size-1 .4 lda VolDirHdr,y sta (ZPPtr1),y dey bpl .4 * Blk 3...n : additional Directory Blocks lda #3 Actual Block ID ldy #2 next blk ptr .41 inc ZPPtr1+1 inc ZPPtr1+1 Next Block dex bmi .40 dec Previous Blk ID sta (ZPPtr1) inc inc next blk id phx plx bne .42 txa .42 sta (ZPPtr1),y bra .41 * BitMap Blocks : 0=Used 1=free .40 jsr GetProDOSCatSize.I X=blk used for boot/dir/bitmap lda VolDirHdr.TB eor #$ff sta Count lda VolDirHdr.TB+1 eor #$ff sta Count+1 ldy #0 .50 lda #%10000000 .5 dex bmi .8 inc Count bne .6 inc Count+1 .6 lsr bne .5 iny bne .50 .7 lda #%10000000 .8 inc Count bne .81 inc Count+1 bne .81 clc rts .81 pha eor (ZPPtr1),y sta (ZPPtr1),y pla lsr bne .8 iny bne .7 inc ZPPtr1+1 bra .7 */-------------------------------------- *\-------------------------------------- D2MotorControl >PULLB MotorOn >PULLB DrvSlt jsr CheckDiskII bcs .9 lda MotorOn asl lda #0 adc #IO.D2.DrvOff adc Slotn0 tax lda $C000,x * clc .9 rts */-------------------------------------- *\-------------------------------------- D2MoveHead >PULLB MoveTo >PULLB MoveFrom >PULLB DrvSlt jsr CheckDiskII bcs .9 .1 lda MoveTo sec sbc MoveFrom beq .8 bcc .2 cmp #2 A>curtrk, must move in bcc .3 lda #2 bra .3 .2 cmp #$fe A136+ * PUSHW = Ptr to 16*256 buffer * ## RETURN VALUE * CC : success * CS : A = Error * A=0, currently starting/seeking... *\-------------------------------------- D2TrkWrite16s >PULLW ZPPtr1 >PULLB TrkNum >PULLB VolNum >PULLB DrvSlt jsr CheckDiskII bcs .9 >LDYAI TRACK16.LEN+1 >SYSCALL2 getmem bcs .9 >STYA ZPPtr2 stx hTrkBuf stz SectNum ldy #TRACK16.GAP1 jsr PutSyncBytePtr2 .1 jsr PutAddrHeadPtr2 jsr HeaderCheckSum ldy #3 .2 lda Checksum,y jsr PutByte44Ptr2 dey bpl .2 jsr PutTailPtr2 ldy #TRACK16.GAP2 jsr PutSyncBytePtr2 jsr PutDataHeadPtr2 jsr PutData jsr PutTailPtr2 ldy #TRACK16.GAP3 jsr PutSyncBytePtr2 inc ZPPtr1+1 inc SectNum lda SectNum cmp #16 bne .1 lda #0 sta (ZPPtr2) jsr D2WriteTrackPtr2 php pha lda hTrkBuf >SYSCALL2 FreeMem pla plp .9 rts */-------------------------------------- *\-------------------------------------- D2TrkReadNIB */-------------------------------------- * # D2TrkWriteNIB * Write a track (NIBBLE) * **In:** * PUSHB = DSSS0000 * PUSHW = Ptr to NIBBLE buffer (0 ended) * ## RETURN VALUE * CC : success * CS : A = Error * A=0, currently starting/seeking... *\-------------------------------------- D2TrkWriteNIB >PULLW ZPPtr1 >PULLB DrvSlt jsr CheckDiskII was it a DISK II ? bcs .9 .9 rts *-------------------------------------- * A=DSSS0000 *-------------------------------------- CheckDiskII pha and #$70 only 0SSS sta Slotn0 lsr lsr lsr lsr ora #$C0 make Cn sta ZPPtr3+1 stz ZPPtr3 ldx #3 4 bytes to check .1 ldy DiskII.OFS,x .2 lda (ZPPtr3),y cmp DiskII.SIG,x bne .9 dex bpl .1 pla all bytes match, Disk II asl lda #0 adc #IO.D2.DrvSel1 adc Slotn0 tax lda $C000,x * clc rts .9 pla lda #MLI.E.NODEV sec rts *-------------------------------------- * A=DSSS0000 *-------------------------------------- DrvSpinCheck ldy #0 lda IO.D2.RData,x .1 cmp IO.D2.RData,x bne .8 spinning dey bne .1 clc CC:not spinning rts .8 sec rts *-------------------------------------- PutSyncBytePtr2 lda #$7f .1 jsr PutBytePtr2 dey bne .1 rts *-------------------------------------- PutAddrHeadPtr2 ldy #2 .1 lda ADDR.Head,y jsr PutBytePtr2 dey bpl .1 rts *-------------------------------------- PutDataHeadPtr2 ldy #2 .1 lda DATA.Head,y jsr PutBytePtr2 dey bpl .1 rts *-------------------------------------- PutTailPtr2 ldy #2 .1 lda TAIL,y jsr PutBytePtr2 dey bpl .1 rts *-------------------------------------- HeaderCheckSum lda VolNum eor TrkNum eor SectNum sta Checksum rts *-------------------------------------- PutData stz Checksum lda ZPPtr1 ldy ZPPtr1+1 clc adc #86 bcc .1 iny clc .1 sta ZPPtr3 sty ZPPtr3+1 adc #86 bcc .2 iny .2 sta ZPPtr4 sty ZPPtr4+1 ldy #85 .3 lda (ZPPtr1),y and #3 tax lda XRW.XX000000,x pha lda (ZPPtr3),y and #3 tax pla ora XRW.00XX0000,x pha lda (ZPPtr4),y and #3 tax pla ora XRW.0000XX00,x eor Checksum sta Checksum tax lda FC2Nib,x jsr PutBytePtr2 dey bpl .3 ldy #0 .4 lda (ZPPtr3),y and #$FC eor Checksum sta Checksum tax lda FC2Nib,x jsr PutBytePtr2 iny bne .4 ldx Checksum lda FC2Nib,x jsr PutBytePtr2 rts *-------------------------------------- PutByte44Ptr2 pha ror jsr .1 pla .1 ora #$AA *-------------------------------------- PutBytePtr2 sta (ZPPtr2) inc ZPPtr2 bne .8 inc ZPPtr2+1 .8 rts *-------------------------------------- D2WriteTrackPtr2 sei ldy #TrkWriter.Size .1 lda TrkWriter-1,y sta $1ff,y dey bne .1 lda hTrkBuf >SYSCALL2 GetMemPtr >STYA ZPPtr1 ldx Slotn0 jsr $200 cli rts *-------------------------------------- CS.END *-------------------------------------- * TrkWriter * X = Slot Cn * ZPPtr1 = Ptr To NibbleBuf *-------------------------------------- TrkWriter .PH $200 TrkWriter.Start lda IO.D2.ReadProt,x lda IO.D2.ReadMode,x bmi .9 Write protected ldy ZPPtr1 stz ZPPtr1 lda (ZPPtr1),y iny bne .10 no chance this happens because mem blocks are $FFF0 aligned.... inc ZPPtr1+1 .10 cmp #$80 if CC, it is a sync byte ora #$80 make sure Bit7 high sta IO.D2.WriteMode,x (5) goto write mode ora IO.D2.WShift,x (4) nop (2) bra .2 (3) .1 lda (ZPPtr1),y (5) as NibbleBuf is page aligned, no page crossing beq .8 (2)(3 if Z) END OF TRACK * nobody will never try to write 00000000, right? cmp #$80 (2) if CC, it is a sync byte ora #$80 (2) make sure Bit7 high sta IO.D2.WLoad,x (5) ora IO.D2.WShift,x (4) keep C unmodified iny (2) bne .2 (2)(3 if nz) * 32us Byte,next page : 2 (beq failed)+5 +2+2+5+4+2+2 (bne failed) + 5 + 3 (bcs succeeded) = 32 inc ZPPtr1+1 (5) bcs .1 (2)(3 if cs) regular 32us byte * 40us Byte,next page : 2 (beq failed) +2+2+5+4+2+2 (bne failed) + 5 + 2 (bcs failed) +2+2+2+3 = 40 nop (2) Sync 40us byte : add 8 cycles nop (2) nop (2) bra .1 (3) * 32us Byte,same page : 5+2 (beq failed) +2+2+5+4+2+3 (bne succeeded) + 2 +2 + 3 (bcs succeeded) = 32 .2 nop (2) nop (2) bcs .1 (2)(3 if cs) regular 32us byte * 40us Byte,same page : 5+2 (beq failed) +2+2+5+4+2+2 (bne failed) + 5 + 2 (bcs failed) +2+2+2+3 = 40 nop (2) Sync 40us byte : add 8 cycles nop (2) nop (2) bra .1 (3) .8 pha (3) make sure 32us elapsed before switching to read mode (beq(3)+pha(3)=beq(2)+cmp(2)+ora(2)) lda IO.D2.ReadMode,x close write mode lda IO.D2.RData,x pla from pha (3) clc rts .9 lda #MLI.E.WRTPROT sec rts TrkWriter.Size .EQ *-TrkWriter.Start .EP *-------------------------------------- ADDR.Head .HS 96AAD5 DATA.Head .HS ADAAD5 TAIL .HS EBAADE *-------------------------------------- Nib2FC .HS 0004 .HS FFFF .HS 080C .HS FF .HS 101418 XRW.XX000000 .HS 008040C0FFFF used in fast prenib as lookup for 2-bit quantities. .HS 1C20 .HS FFFFFF .HS 24282C3034 .HS FFFF .HS 383C4044484C .HS FF .HS 5054585C606468 XRW.00XX0000 .HS 00201030 used in fast prenib. endmrks .HS DEAAEB table using 'unused' nibbles ($C4,$C5,$C6,$C7) .HS FFFFFFFF .HS 6C .HS FF .HS 707478 .HS FFFFFF .HS 7C .HS FFFF .HS 8084 .HS FF .HS 888C9094989CA0 XRW.0000XX00 .HS 0008040C used in fast prenib. .HS FF .HS A4A8AC .HS FF .HS B0B4B8BCC0C4C8 .HS FFFF .HS CCD0D4D8DCE0 .HS FF .HS E4E8ECF0F4F8FC *-------------------------------------- dnibl2 .HS 00 dnibl3 .HS 00 dnibl4 .HS 00 FC2Nib .HS 96 .HS 02000097 .HS 0100009A .HS 0300009B .HS 0002009D .HS 0202009E .HS 0102009F .HS 030200A6 .HS 000100A7 .HS 020100AB .HS 010100AC .HS 030100AD .HS 000300AE .HS 020300AF .HS 010300B2 .HS 030300B3 .HS 000002B4 .HS 020002B5 .HS 010002B6 .HS 030002B7 .HS 000202B9 .HS 020202BA .HS 010202BB .HS 030202BC .HS 000102BD .HS 020102BE .HS 010102BF .HS 030102CB .HS 000302CD .HS 020302CE .HS 010302CF .HS 030302D3 .HS 000001D6 .HS 020001D7 .HS 010001D9 .HS 030001DA .HS 000201DB .HS 020201DC .HS 010201DD .HS 030201DE .HS 000101DF .HS 020101E5 .HS 010101E6 .HS 030101E7 .HS 000301E9 .HS 020301EA .HS 010301EB .HS 030301EC .HS 000003ED .HS 020003EE .HS 010003EF .HS 030003F2 .HS 000203F3 .HS 020203F4 .HS 010203F5 .HS 030203F6 .HS 000103F7 .HS 020103F9 .HS 010103FA .HS 030103FB .HS 000303FC .HS 020303FD .HS 010303FE .HS 030303FF *-------------------------------------- LC.BitMap .HS 80402010080402018040201008040201 *-------------------------------------- ProDOS.Boot .HS 01.38.b0.03.4c.32.a1.86.43.c9.03.08.8a.29.70.4a .HS 4a.4a.4a.09.c0.85.49.a0.ff.84.48.28.c8.b1.48.d0 .HS 3a.b0.0e.a9.03.8d.00.08.e6.3d.a5.49.48.a9.5b.48 .HS 60.85.40.85.48.a0.63.b1.48.99.94.09.c8.c0.eb.d0 .HS f6.a2.06.bc.1d.09.bd.24.09.99.f2.09.bd.2b.09.9d .HS 7f.0a.ca.10.ee.a9.09.85.49.a9.86.a0.00.c9.f9.b0 .HS 2f.85.48.84.60.84.4a.84.4c.84.4e.84.47.c8.84.42 .HS c8.84.46.a9.0c.85.61.85.4b.20.12.09.b0.68.e6.61 .HS e6.61.e6.46.a5.46.c9.06.90.ef.ad.00.0c.0d.01.0c .HS d0.6d.a9.04.d0.02.a5.4a.18.6d.23.0c.a8.90.0d.e6 .HS 4b.a5.4b.4a.b0.06.c9.0a.f0.55.a0.04.84.4a.ad.02 .HS 09.29.0f.a8.b1.4a.d9.02.09.d0.db.88.10.f6.29.f0 .HS c9.20.d0.3b.a0.10.b1.4a.c9.ff.d0.33.c8.b1.4a.85 .HS 46.c8.b1.4a.85.47.a9.00.85.4a.a0.1e.84.4b.84.61 .HS c8.84.4d.20.12.09.b0.17.e6.61.e6.61.a4.4e.e6.4e .HS b1.4a.85.46.b1.4c.85.47.11.4a.d0.e7.4c.00.20.4c .HS 3f.09.26.50.52.4f.44.4f.53.20.20.20.20.20.20.20 .HS 20.20.a5.60.85.44.a5.61.85.45.6c.48.00.08.1e.24 .HS 3f.45.47.76.f4.d7.d1.b6.4b.b4.ac.a6.2b.18.60.4c .HS bc.09.a9.9f.48.a9.ff.48.a9.01.a2.00.4c.79.f4.20 .HS 58.fc.a0.1c.b9.50.09.99.ae.05.88.10.f7.4c.4d.09 .HS aa.aa.aa.a0.d5.ce.c1.c2.cc.c5.a0.d4.cf.a0.cc.cf .HS c1.c4.a0.d0.d2.cf.c4.cf.d3.a0.aa.aa.aa.a5.53.29 .HS 03.2a.05.2b.aa.bd.80.c0.a9.2c.a2.11.ca.d0.fd.e9 .HS 01.d0.f7.a6.2b.60.a5.46.29.07.c9.04.29.03.08.0a .HS 28.2a.85.3d.a5.47.4a.a5.46.6a.4a.4a.85.41.0a.85 .HS 51.a5.45.85.27.a6.2b.bd.89.c0.20.bc.09.e6.27.e6 .HS 3d.e6.3d.b0.03.20.bc.09.bc.88.c0.60.a5.40.0a.85 .HS 53.a9.00.85.54.a5.53.85.50.38.e5.51.f0.14.b0.04 .HS e6.53.90.02.c6.53.38.20.6d.09.a5.50.18.20.6f.09 .HS d0.e3.a0.7f.84.52.08.28.38.c6.52.f0.ce.18.08.88 .HS f0.f5.bd.8c.c0.10.fb.00.00.00.00.00.00.00.00.00 *-------------------------------------- * Block 2 : First DIR block *-------------------------------------- VolDirHdr VolDirHdr.Prev .BS 2 pointer to previous block VolDirHdr.Next .BS 2 pointer to next block VolDirHdr.Name .BS 16 .HS 00.00.00.00.00.00.00.00 VolDirHdr.CT .BS 4 Creation time VolDirHdr.VER .BS 1 VolDirHdr.MVER .BS 1 .HS C3.27.0D access/EL/EPB .DA 0 File Count=0 (only VDH) VolDirHdr.BMPtr .BS 2 bitmap pointer (Block 2..n are Volume directory) VolDirHdr.TB .BS 2 Total Blocks VolDirHdr.size .EQ *-VolDirHdr *-------------------------------------- VolDirHdr.Options .BS 1 VolDirHdr.CatSize .BS 1 *-------------------------------------- DiskII.OFS .HS 010305FF DiskII.SIG .HS 20000300 *-------------------------------------- DrvSlt .BS 1 Slotn0 .BS 1 hTrkBuf .BS 1 MoveFrom .BS 1 MoveTo .BS 1 Checksum .BS 1 SectNum .BS 1 TrkNum .BS 1 VolNum .BS 1 MotorOn .BS 1 montimel .BS 1 montimeh .BS 1 Count .BS 2 *-------------------------------------- MAN SAVE USR/SRC/LIB/LIBBLKDEV.S ASM