PR#3 PREFIX /A2OSX.BUILD NEW INC 1 AUTO 6 .LIST OFF .OP 65C02 .OR $2000 .TF /A2OSX.BUILD/LIB/LIBBLKDEV.O *-------------------------------------- .INB /A2OSX.BUILD/INC/MACROS.I .INB /A2OSX.BUILD/INC/A2OSX.I .INB /A2OSX.BUILD/INC/PRODOS.I .INB /A2OSX.BUILD/INC/LIBBLKDEV.I *-------------------------------------- * NIBBLE track len = $1A00 (6656) bytes: * *-------------------------------------- GAP1 .EQ 48 GAP2 .EQ 6 GAP3 .EQ 27 *-------------------------------------- Status.PrvDrvOff .EQ $80 Waiting old drive stop spining Status.DrvOn .EQ $81 Waiting target drive spin Status.seek .EQ $82 targetdrive seeking *-------------------------------------- D2Ph0Off .EQ $C080 D2Ph0On .EQ $C081 D2Ph1Off .EQ $C082 D2Ph1On .EQ $C083 D2Ph2Off .EQ $C084 D2Ph2On .EQ $C085 D2Ph3Off .EQ $C086 D2Ph3On .EQ $C087 D2DrvOff .EQ $C088 D2DrvOn .EQ $C089 D2DrvSel1 .EQ $C08A D2DrvSel2 .EQ $C08B D2WShift .EQ $C08C W D2WLoad .EQ $C08D W D2RData .EQ $C08C R D2ReadProt .EQ $C08D R D2ReadMode .EQ $C08E R D2WriteMode .EQ $C08F W *-------------------------------------- ZPPtr1 .EQ ZPLIB ZPPtr2 .EQ ZPLIB+2 ZPPtr3 .EQ ZPLIB+4 *-------------------------------------- * 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 D2TrkR16s .DA D2TrkRNIB .DA D2TrkW16s .DA D2TrkWNIB L.TrkWriter .DA TrkWriter L.ProDOS.Boot .DA ProDOS.Boot .DA 0 */-------------------------------------- * # GetProDOSCatSize * Compute space needed for ProDOS Catalog * ## In : * PUSHW = DevSize (in 512b blocks) * ## Out : * X=BlockCount (max 22) * Y,A=BufSize (max $4400) *\-------------------------------------- GetProDOSCatSize >PULLAX A=DevSizeLo GetProDOSCatSizeAX clc for now, no partial bitmap blk to add tay DevSize is xxxxxxxx00000000 ? beq .1 sec .1 txa Get DevSizeHI bit #$0f DevSize is xxxx000000000000 ? beq .2 sec .2 php lsr lsr lsr lsr plp adc #6 at least, 1(ProDOS)+1(SOS)+4(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) * PUSHW = VolName (PSTR) * PUSHW = DstBuf (Zero filled) * Blk0 : ProDOS.BootBlk * Blk1 : SOS.BootBlk * Blk2,3,4,5 : Volume Directory * Blk6.... : 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 >PULLW VolDirHdr.TB ldx #3 .10 lda DATELO,x sta VolDirHdr.CT,x dex bpl .10 * Boot Code >LDYA L.ProDOS.Boot >STYA ZPPtr3 ldy #0 ldx #2 2 pages .1 lda (ZPPtr3),y sta (ZPPtr1),y iny bne .1 inc ZPPtr3+1 inc ZPPtr1+1 dex bne .1 inc ZPPtr1+1 Skip Blk 2 (SOS boot code) inc ZPPtr1+1 * Directory Blocks lda (ZPPtr2) VolName Len and #$0f make sure 15 bytes max tay ora #$F0 Volume Directory Header sta VolDirHdr.Name .3 lda (ZPPtr2),y sta VolDirHdr.Name,y dey bne .3 ldy #VolDirHdr.size-1 .4 lda VolDirHdr,y sta (ZPPtr1),y dey bpl .4 inc ZPPtr1+1 inc ZPPtr1+1 Blk 3 ldy #2 lda #2 sta (ZPPtr1) lda #4 sta (ZPPtr1),y inc ZPPtr1+1 inc ZPPtr1+1 Blk 4 lda #3 sta (ZPPtr1) lda #5 sta (ZPPtr1),y inc ZPPtr1+1 inc ZPPtr1+1 Blk 5 lda #4 sta (ZPPtr1) inc ZPPtr1+1 inc ZPPtr1+1 Blk 6 * BitMap Blocks : 0=Used 1=free >LDAX VolDirHdr.TB jsr GetProDOSCatSizeAX 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 beq .88 .81 pha eor (ZPPtr1),y sta (ZPPtr1),y pla lsr bne .8 iny bne .7 inc ZPPtr1+1 bra .7 .88 clc rts */-------------------------------------- *\-------------------------------------- D2TrkRNIB */-------------------------------------- *\-------------------------------------- D2TrkR16s */-------------------------------------- * # TrkW16s * Write a track (16 sectors) * ## In: * PUSHW = Ptr to 16*256 buffer * PUSHB = TrackNum * 4 : 0->140+ * PUSHB = DSSS0000 * ## Out: * CC : success * CS : A = Error * A=0, currently starting/seeking... *\-------------------------------------- D2TrkW16s clc rts */-------------------------------------- * # TrkWNIB * Write a track (NIBBLE) * ## In: * PUSHW = Ptr to NIBBLE buffer (0 ended) * PUSHB = TrackNum * 4 : 0->140+ * PUSHB = DSSS0000 * ## Out: * CC : success * CS : A = Error * A=0, currently starting/seeking... *\-------------------------------------- D2TrkWNIB >PULLB DrvSlt >PULLB TrkNum >PULLW ZPPtr1 lda Status Lib is busy....? beq .10 lda DrvSlt cmp DrvSltInUse resume previous access ? .10 lda DEVNUM last drive accessed by ProDOS and #$F0 only DSSS pha jsr CheckDiskII was it a DISK II ? bcs .1 no, no need to check if spinning pla pha jsr DrvSpinCheck bcc .1 not spinning....continue pla sta D2DrvOff,x lda #Status.PrvDrvOff jmp SetStatusAndExit .1 pla cmp DrvSlt * beq lda DrvSlt jsr DrvTrkSelect bcs .9 ldy #TrkWriter.Size .7 lda TrkWriter,y sta UsrBuf256,y dey bne .7 jmp UsrBuf256 clc .9 rts *-------------------------------------- SetStatusAndExit sta Status ldy DrvSlt sty DrvSltInUse clc rts *-------------------------------------- LIB.LOAD LIB.UNLOAD clc rts *-------------------------------------- * A=DSSS0000 * Y=target Track Number * 4 *-------------------------------------- DrvTrkSelect jsr DrvSelect clc rts *-------------------------------------- * A=DSSS0000 *-------------------------------------- CheckDiskII and #$70 only 0SSS lsr lsr lsr ora #$C0 make Cn sta .2+2 ldx #3 4 bytes to check .1 ldy DiskII.OFS,x .2 lda $C000,y Self Modified cmp DiskII.SIG,x bne .9 dex bpl .1 clc all bytes match, Disk II rts .9 sec rts *-------------------------------------- * A=DSSS0000 *-------------------------------------- DrvSpinCheck jsr DrvSelect ldy #0 lda D2RData,x .1 cmp D2RData,x bne .8 spinning dey bne .1 clc CC:not spinning rts .8 sec rts *-------------------------------------- * A=DSSS0000 *-------------------------------------- DrvSelect pha and #$70 tax pla asl adc #D2DrvSel1 sta .1+1 .1 lda D2DrvSel1,x Drv 1/2 select lda D2ReadMode,x Make sure readmode rts *-------------------------------------- CS.END DiskII.OFS .HS 010305FF DiskII.SIG .HS 20000300 DrvSlt .BS 1 TrkNum .BS 1 *-------------------------------------- Status .BS 1 DrvSltInUse .BS 1 Count .BS 2 *-------------------------------------- * TrkWriter * X = Slot Cn * ZPPtr1 = Ptr To NibbleBuf *-------------------------------------- TrkWriter .PH $200 TrkWriter.Start lda D2ReadMode,x lda D2ReadProt,x bmi .9 Write protected php sei ldy #0 .1 lda (ZPPtr1),y (5) as NibbleBuf is page alligned, 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 D2WriteMode,x (5) ora D2WShift,x (4) keep C unmodified iny (2) bne .2 (2)(3 if nz) inc ZPPtr1+1 (5) bcs .1 (2)(3 if cs) regular 32us byte * 32us Byte,next page : 5+2 (beq failed) +2+2+5+4+2+2 (bne failed) + 5 + 3 (bcs succeeded) = 32 nop (2) Sync 40us byte : add 8 cycles nop (2) nop (2) bra .1 (3) * 40us Byte,next page : 5+2 (beq failed) +2+2+5+4+2+2 (bne failed) + 5 + 2 (bcs failed) +2+2+2+3 = 40 .2 nop (2) nop (2) bcs .1 (2)(3 if cs) regular 32us byte * 32us Byte,same page : 5+2 (beq failed) +2+2+5+4+2+3 (bne succeeded) + 2 +2 + 3 (bcs succeeded) = 32 nop (2) Sync 40us byte : add 8 cycles nop (2) nop (2) bra .1 (3) * 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 .8 pha (3) make sure 32us elapsed before switching to read mode (beq(3)+pha(3)=beq(2)+cmp(2)+ora(2)) lda D2ReadMode,x close write mode lda D2RData,x pla from pha (3) plp clc rts .9 lda #$2B Write Protected sec rts TrkWriter.Size .EQ *-TrkWriter.Start .EP *-------------------------------------- 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 *-------------------------------------- VolDirHdr .DA 0 pointer to previous block .DA 3 pointer to next block VolDirHdr.Name .BS 16 .HS 00.00.00.00.00.00.00.00 VolDirHdr.CT .BS 4 Creation time .HS 01.00.C3.27.0D version/min version/access/EL/EPB .DA 0 File Count=0 (only VDH) .DA 6 bitmap pointer (Block 2..5 are Volume directory) VolDirHdr.TB .BS 2 Total Blocks VolDirHdr.size .EQ *-VolDirHdr *-------------------------------------- MAN SAVE /A2OSX.SRC/LIB/LIBBLKDEV.S ASM