From ce26640372ac20702478d4c5587a28214db69ae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20GIBERT?= Date: Tue, 21 Apr 2020 08:19:17 +0200 Subject: [PATCH] Kernel 0.94 --- .Floppies/A2OSX.BLANK.woz | Bin 0 -> 234496 bytes .Floppies/A2OSX.BOOT.po | Bin 143360 -> 143360 bytes .Floppies/A2OSX.BOOT.woz | Bin 0 -> 234496 bytes .Floppies/A2OSX.BUILD.po | Bin 33553920 -> 33553920 bytes INC/LIBBLKDEV.I.txt | 2 + LIB/LIBBLKDEV.S.txt | 120 +++- ProDOS.FX/ProDOS.S.XRW.txt | 1272 +++++++++++++++++++----------------- 7 files changed, 790 insertions(+), 604 deletions(-) create mode 100644 .Floppies/A2OSX.BLANK.woz create mode 100644 .Floppies/A2OSX.BOOT.woz diff --git a/.Floppies/A2OSX.BLANK.woz b/.Floppies/A2OSX.BLANK.woz new file mode 100644 index 0000000000000000000000000000000000000000..18f568ea339a23248d4409c02051d67d279f1080 GIT binary patch literal 234496 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 MYCfW49rDxq|Jf}Ry9Pz2u$5w$SgP(@MMQQA{l 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 Hep&wyr*%Oi literal 0 HcmV?d00001 diff --git a/.Floppies/A2OSX.BUILD.po b/.Floppies/A2OSX.BUILD.po index dccaf625e28b94a1b4bf814f1cc3e7da4842f4f7..a6e603f34158acc90dddc5988b9027bc6340ceb8 100644 GIT binary patch delta 12716 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 delta 11173 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%0AdX@7(YK}wI_4?**Hjo&`#Bo3PK@w9FjS>t zhuwKn^l(m2XPqyI#F-1%HGn1E;CukCb-?;`Pv<>GmTXKX8#A06Gp{%&X0v3Gku1t0 zi^h{h6P$}Ce&Sr7%{p_k;o_*sHa5d0j$&l7x-;9i1H5qz597YKfl;Fk#QBlrx# zX9?~n_+^4$A^25-UnBS&!LJkie*~W=_yWOi5d05<-z4}gg5M_ip9BvOe39Tw1iJ{n zOzu@TUZSM)2nZe?jn<1b;>F z*92cB_#1++5&SK|*9rcP;2Q*gPw)=}|48tE3I2)Tp9%hj;9m*;jo{x2{)6C~1pi6! zUj*OUikUXd04%@(9)JSy1iSzx;0^cyzJMR#52%0uAP@)wBtOAG2oMU40!9OBAPfix zB7jIB3Wx?`01dzc0uT$t0b_u%z&IctNB|OnBp?}pbpvaGR6qyl0RxZ*h(J1!0b~M3 zAPX1|OaLYV*+333378C+fLy=~SO6=K2TTF-fvLbW;4WY~Fawwg%mQWubAY+PJYYVs z09Xjz4cr6V3oHWe0~P~IfTh4Ppa8G|%Yj0m2(Sai!2Li8PztO7Rsv8elC@2h;-(0PBGDz=OaBpaEzE9Kc54Az%}*86ZFt&;0FMEW15W@?0$spfU?1=lupc-8IDvz}A)p&L z3_J}S0geL4fM1mt^(fx*MM(<>%e!w4d8p=2jEBGzratx&%iIhufT7> T@4z3xP2f-9FXk8=F<<+CJ*0Z9 diff --git a/INC/LIBBLKDEV.I.txt b/INC/LIBBLKDEV.I.txt index 71649dba..c8d37847 100644 --- a/INC/LIBBLKDEV.I.txt +++ b/INC/LIBBLKDEV.I.txt @@ -4,6 +4,8 @@ NEW *-------------------------------------- LIBBLKDEV.GetProDOSCatSize .EQ 4 LIBBLKDEV.BuildProDOSCat .EQ 6 +LIBBLKDEV.D2TrkRead16s .EQ 8 +LIBBLKDEV.D2TrkWrite16s .EQ 10 *-------------------------------------- MAN SAVE INC/LIBBLKDEV.I diff --git a/LIB/LIBBLKDEV.S.txt b/LIB/LIBBLKDEV.S.txt index 193d5b14..6a22b7b9 100644 --- a/LIB/LIBBLKDEV.S.txt +++ b/LIB/LIBBLKDEV.S.txt @@ -10,11 +10,21 @@ NEW .INB INC/MLI.I .INB INC/IO.D2.I *-------------------------------------- -* NIBBLE track len = $1A00 (6656) bytes +TRACK16.LEN .EQ $19F8 (6648) bytes *-------------------------------------- -GAP1 .EQ 48 -GAP2 .EQ 6 -GAP3 .EQ 27 +TRACK16.GAP1 .EQ 64+8 +*Address field = D5AA96 + 4x2 + DEAAEB = 14 +TRACK16.GAP2 .EQ 6 +*Data field = D5AAAD + 342 + CS + DEAAEB = 349 +TRACK16.GAP3 .EQ 42 +*-------------------------------------- +TRACK9.LEN .EQ $19F8 (6648) bytes +*-------------------------------------- +TRACK9.GAP1 .EQ 51 +*Address field = D5AA96 + 4x2 + DEAAEB = 14 +TRACK9.GAP2 .EQ 6 +*Data field = D5AAAD + 342 + 342 + CS + DEAAEB = 691 +TRACK9.GAP3 .EQ 42 *-------------------------------------- Status.PrvDrvOff .EQ $80 Waiting old drive stop spinning Status.DrvOn .EQ $81 Waiting target drive spin @@ -42,10 +52,10 @@ CS.START cld .DA LIB.UNLOAD .DA GetProDOSCatSize .DA BuildProDOSCat - .DA D2TrkR16s - .DA D2TrkRNIB - .DA D2TrkW16s - .DA D2TrkWNIB + .DA D2TrkRead16s + .DA D2TrkWrite16s + .DA D2TrkRreadNIB + .DA D2TrkWriteNIB L.TrkWriter .DA TrkWriter L.ProDOS.Boot .DA ProDOS.Boot .DA 0 @@ -277,30 +287,68 @@ BuildProDOSCat >PULLW ZPPtr1 DstBuf bra .7 */-------------------------------------- *\-------------------------------------- -D2TrkRNIB +D2TrkRead16s */-------------------------------------- -*\-------------------------------------- -D2TrkR16s -*/-------------------------------------- -* # D2TrkW16s +* # D2TrkWrite16s * Write a track (16 sectors) * **In:** -* PUSHW = Ptr to 16*256 buffer -* PUSHB = TrackNum * 4 : 0->140+ * PUSHB = DSSS0000 +* PUSHB = TrackNum * 4 : 0->136+ +* PUSHW = Ptr to 16*256 buffer * ## RETURN VALUE * CC : success * CS : A = Error * A=0, currently starting/seeking... *\-------------------------------------- -D2TrkW16s >PULLB DrvSlt +D2TrkWrite16s >PULLW ZPPtr1 >PULLB TrkNum - >PULLW ZPPtr1 + >PULLB DrvSlt + + >LDYAI TRACK16LEN+1 + >SYSCALL getmem + bcs .9 + + >STYA ZPPtr2 + stx TrkBuf + + lda #254 + sta VolNum + stz SectNum + + ldy #TRACK16.GAP1 + + lda #$7f + +.1 jsr PutBytePtr2 + dey + bne .1 + + lda #$D5 + jsr PutBytePtr2 + + lda #$AA + jsr PutBytePtr2 + + lda #$96 + jsr PutBytePtr2 + + jsr HeaderCheckSum + + ldy #3 + +.2 lda Checksum,y + jsr PutByte44Ptr2 + dey + bpl .2 + clc - rts +.9 rts */-------------------------------------- -* # D2TrkWNIB +*\-------------------------------------- +D2TrkReadNIB +*/-------------------------------------- +* # D2TrkWriteNIB * Write a track (NIBBLE) * **In:** * PUSHW = Ptr to NIBBLE buffer (0 ended) @@ -311,7 +359,7 @@ D2TrkW16s >PULLB DrvSlt * CS : A = Error * A=0, currently starting/seeking... *\-------------------------------------- -D2TrkWNIB >PULLB DrvSlt +D2TrkWriteNIB >PULLB DrvSlt >PULLB TrkNum >PULLW ZPPtr1 @@ -400,6 +448,13 @@ DrvSpinCheck jsr DrvSelect *-------------------------------------- * A=DSSS0000 *-------------------------------------- +HeaderCheckSum lda VolNum + eor TrkNum + eor SectNum + + sta Checksum + rts +*-------------------------------------- DrvSelect pha and #$70 tax @@ -413,6 +468,20 @@ DrvSelect pha lda IO.D2.ReadMode,x Make sure readmode rts *-------------------------------------- +PutByte44Ptr2 pha + rol + jsr .1 + + pla + +.1 ora #$AA +*-------------------------------------- +PutBytePtr2 sta ZPPtr2 + inc ZPPtr2 + bne .8 + inc ZPPtr2+1 +.8 rts +*-------------------------------------- CS.END *-------------------------------------- * TrkWriter @@ -432,7 +501,8 @@ TrkWriter.Start lda IO.D2.ReadMode,x .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? +* 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.WriteMode,x (5) @@ -535,9 +605,15 @@ VolDirHdr.CatSize .BS 1 *-------------------------------------- DiskII.OFS .HS 010305FF DiskII.SIG .HS 20000300 - +*-------------------------------------- DrvSlt .BS 1 +TrkBuf .BS 1 + +Checksum .BS 1 +SectNum .BS 1 TrkNum .BS 1 +VolNum .BS 1 + *-------------------------------------- Status .BS 1 DrvSltInUse .BS 1 diff --git a/ProDOS.FX/ProDOS.S.XRW.txt b/ProDOS.FX/ProDOS.S.XRW.txt index 96bc2dfd..e5757cd1 100644 --- a/ProDOS.FX/ProDOS.S.XRW.txt +++ b/ProDOS.FX/ProDOS.S.XRW.txt @@ -159,13 +159,13 @@ L538E lda A4L get command # L5398 ldy #$40 64 retries sty retrycnt -L539D jsr rdadr16 read next address field. +L539D jsr XRW.ReadAddr read next address field. bcc L53BE branch if read ok. L53A4 dec retrycnt one less chance. bpl L539D branch to retry. - lda #$27 anticipate a bad drive error. + lda #MLI.E.IO anticipate a bad drive error. dec seekcnt can only recalibrate once. bne hndlerr @@ -211,7 +211,7 @@ L53D5 lda XRW.AddrField.S is this the right sector ? lsr the carry will tell. bcc L53F4 branch if write - jsr read16 + jsr XRW.Read bcs L53A4 if bad read L53E7 lda #$00 @@ -222,10 +222,10 @@ hndlerr sec lda IO.D2.DrvOff,x turn off rts *-------------------------------------- -L53F4 jsr write16 write nibbles +L53F4 jsr XRW.Write statdne bcc L53E7 if no errors. - lda #$2B disk write protected. + lda #MLI.E.WRTPROT disk write protected. bne hndlerr always L53FD ldx A2L @@ -235,428 +235,14 @@ L53FD ldx A2L lda IO.D2.RData,x keep in read mode bra statdne *-------------------------------------- -* fast seek subroutine -* A = desired track -* curtrk = current 1/4 track -* -* montimel,h are incremented by the # of 100us quantums required by seek for motor on time overlap. -* variables used: curtrk, A2L, montimel, montimeh -*-------------------------------------- -XRW.Seek asl transform into 1/4 tracks - asl - - pha - - jsr XRW.GetUnitIdx get index to previous track - lda XRW.LastTrackPos,y for current drive. - - sta curtrk current position. - - pla - - sta XRW.LastTrackPos,y - -.1 lda XRW.LastTrackPos,y - - sec - sbc curtrk - beq .8 - - bcc .2 - - cmp #3 A>curtrk, must move in - bcc .3 - - lda #3 - bra .3 - -.2 -* >DEBUG - cmp #$fd A0000FE -* dnibl3 abcdef-->0000DC -* dnibl4 abcdef-->0000BA -* origin = $D200 (page boundary) -* page align the following tables: -*-------------------------------------- -dnibl2 .HS 00 -dnibl3 .HS 00 -dnibl4 .HS 00 -*-------------------------------------- -* 6-bit to 7-bit nibl conversion table -* -* codes with more than one pair of adjacent zeroes -* or with no adjacent ones (except B7) are excluded. -*-------------------------------------- -nibl .HS 960200 - .HS 00970100009A0300 - .HS 009B0002009D0202 - .HS 009E0102009F0302 - .HS 00A6000100A70201 - .HS 00AB010100AC0301 - .HS 00AD000300AE0203 - .HS 00AF010300B20303 - .HS 00B3000002B40200 - .HS 02B5010002B60300 - .HS 02B7000202B90202 - .HS 02BA010202BB0302 - .HS 02BC000102BD0201 - .HS 02BE010102BF0301 - .HS 02CB000302CD0203 - .HS 02CE010302CF0303 - .HS 02D3000001D60200 - .HS 01D7010001D90300 - .HS 01DA000201DB0202 - .HS 01DC010201DD0302 - .HS 01DE000101DF0201 - .HS 01E5010101E60301 - .HS 01E7000301E90203 - .HS 01EA010301EB0303 - .HS 01EC000003ED0200 - .HS 03EE010003EF0300 - .HS 03F2000203F30202 - .HS 03F4010203F50302 - .HS 03F6000103F70201 - .HS 03F9010103FA0301 - .HS 03FB000303FC0203 - .HS 03FD010303FE0303 - .HS 03FF -*-------------------------------------- -* nibl buffer 'nbuf2' must be on a page boundary !!! -*-------------------------------------- -nbuf2 .BS 86 nibl buffer for read/write of low 2-bits of each byte. -XRW.ReqTrack .HS 00 -XRW.ReqSector .HS 00 -ibstat .HS 00 -XRW.LastTrackPos .EQ * -XRW.LastUnitUsed .HS 00 -curtrk .HS 00 - .HS 00000000000000 for slots 1 thru 7 - .HS 00000000000000 drives 1 & 2 -retrycnt .HS 00 -seekcnt .HS 00 -countn .EQ * 'must find' count. -last .HS 00 'odd bit' nibls. - -csum .HS 00 used for address header cksum -XRW.AddrField .HS 00 AddrField Checksum -XRW.AddrField.S .HS 00 AddrField Sector -XRW.AddrField.T .EQ * AddrField Track -montimel .HS 00 -XRW.AddrField.V .EQ * AddrField Volume -montimeh .HS 00 -*-------------------------------------- -* delays a specified number of 100 usec intervals for motor timing. -* on entry: acc holds number of 100 usec intervals to delay. -* on exit: acc = 0, x = 0, y = unchanged, carry set. -* montimel, montimeh are incremented once per 100 usec interval -* for motor on timing. -*-------------------------------------- -XRW.Wait100ms lda #1 - -XRW.Wait100msA -.1 ldx #$11 delay 86 usec - -.2 dex - bne .2 - - inc montimel - bne .3 - - inc montimeh - -.3 sec - sbc #$01 - bne .1 - - rts -*-------------------------------------- -* read address field subroutine (16-sector format) -* -* reads volume, track and sector. -* on entry: x = slot# times $10, read mode -* on exit: carry set if error, else if no error: -* acc=$AA, y=0, x=unchanged, carry clear, -* ccstv contains chksum,sector,track & volume read. -* uses temps: count,last,csum & 4 bytes at ccstv -* expects: original 10-sector normal density nibls (4-bit) odd bits then even. -* observe 'no page cross' warnings on some branches !!! -*-------------------------------------- -rdadr16 ldy #$FC - sty countn 'must find' count - - ldx A2L get slot # - -L569D iny - bne L56A5 low order of count. - - inc countn (2k nibles to find address mark - beq rderr else error) - -L56A5 lda IO.D2.RData,x read nibl - bpl L56A5 *** no page cross *** - -L56AA cmp #$D5 address mark 1 ? - bne L569D - - nop nibl delay - -L56AF lda IO.D2.RData,x - bpl L56AF *** no page cross *** - - cmp #$AA address mark 2 ? - bne L56AA if not, is it address mark 1 ? - - ldy #$03 index for 4 byte read - -L56BA lda IO.D2.RData,x - bpl L56BA *** no page cross *** - - cmp #$96 address mark 3 ? - bne L56AA if not, is it address mark 1 - - sei no interrupts until address is tested. - lda #$00 init checksum - -L56C6 sta csum - -L56C9 lda IO.D2.RData,x read 'odd bit' nibl - bpl L56C9 *** no page cross *** - - rol align odd bits, '1' into lsb. - sta last save them. - -L56D2 lda IO.D2.RData,x read 'even bit' nibl - bpl L56D2 *** no page cross *** - - and last merge odd and even bits. - sta XRW.AddrField,y store data byte. - eor csum - dey - bpl L56C6 loop on 4 data bytes. - - tay if final checksum non-zero, - bne rderr then error. - -L56E6 lda IO.D2.RData,x first bit-slip nibl - bpl L56E6 *** no page cross *** - - cmp #$DE - bne rderr - - nop delay - -L56F0 lda IO.D2.RData,x second bit-slip nible - bpl L56F0 *** no page cross *** - - cmp #$AA - bne rderr - - clc normal read ok - rts - -rderr sec - rts -*-------------------------------------- -* read subroutine (16-sector format) -* -* reads encoded bytes into nbuf1 and nbuf2. -* first reads nbuf2 high to low, then nbuf1 low to high. -* on entry: x=slot# times $10, read mode -* on exit: carry set if error, else if no error: -* acc=$AA, x=unchanged, y=0, carry clear. -* observe 'no page cross' on some branches !! -*-------------------------------------- -read16 txa get slot # - ora #$8C prepare mods to read routine. - sta rd4+1 warning: the read routine is - sta rd5+1 self modified !! - sta rd6+1 - sta rd7+1 - sta rd8+1 - lda buf modify storage addresses also - ldy buf+1 - sta ref3+1 - sty ref3+2 - sec - sbc #$54 - bcs L571F branch if no borrow - dey -L571F sta ref2+1 - sty ref2+2 - sec - sbc #$57 - bcs L572B branch if no borrow - dey -L572B sta ref1+1 - sty ref1+2 - ldy #$20 32 tries to find -L5733 dey - beq L576D branch if can't find data header marks -L5736 lda IO.D2.RData,x - bpl L5736 -L573B eor #$D5 1st data mark - bne L5733 - nop delay -L5740 lda IO.D2.RData,x - bpl L5740 - cmp #$AA 2nd data mark. - bne L573B if not, check for 1st again - nop -L574A lda IO.D2.RData,x - bpl L574A - cmp #$AD 3rd data mark - bne L573B if not, check for data mark 1 again - ldy #$AA - lda #$00 -L5757 sta pcl use z-page for keeping checksum -rd4 ldx IO.D2.RData+$60 warning: self modified - bpl rd4 - lda dnibl-$96,x - sta nbuf2-$AA,y save the two-bit groups in nbuf. - eor pcl update checksum. - iny next position in nbuf. - bne L5757 loop for all $56 two-bit groups. - ldy #$AA now read directly into user buffer. - bne rd5 always taken. -L576D sec error - rts -ref1 sta $1000,y warning: self modified -rd5 ldx IO.D2.RData+$60 warning: self modified - bpl rd5 - eor dnibl-$96,x get actual 6-bit data from dnib table. - ldx nbuf2-$AA,y get associated two-bit pattern - eor dnibl2,x and combine to form whole byte. - iny - bne ref1 loop for $56 bytes. - pha save for now, no time to store... - and #$FC strip low bits. - ldy #$AA prepare for next $56 bytes -rd6 ldx IO.D2.RData+$60 warning: self modified - bpl rd6 - eor dnibl-$96,x - ldx nbuf2-$AA,y - eor dnibl3,x -ref2 sta $1000,y warning: self modified - iny - bne rd6 loop unil this group of $56 read - -rd7 ldx IO.D2.RData+$60 warning: self modified - bpl rd7 - and #$FC - ldy #$AC last group is $54 long -L57A5 eor dnibl-$96,x - ldx nbuf2-$AC,y - eor dnibl4,x combine to form full byte -ref3 sta $1000,y warning: self modified - -rd8 ldx IO.D2.RData+$60 warning: self modified - bpl rd8 - iny - bne L57A5 - and #$FC - eor dnibl-$96,x checksum ok ? - bne L57CC error if not. - ldx A2L test end marks. -L57C2 lda IO.D2.RData,x - bpl L57C2 - cmp #$DE - clc - beq L57CD branch if good trailer -L57CC sec -L57CD pla place last byte into user buffer - ldy #$55 - sta (buf),y +XRW.GetUnitIdx pha preserve acc across call + lda unitnum DSSS0000 + lsr + lsr + lsr + lsr + tay 0000DSSS index to table. + pla restore acc rts *-------------------------------------- * determine if motor is stopped @@ -678,164 +264,12 @@ XRW.CheckMotorOnX cmp IO.D2.RData,x has shift reg changed ? bne .9 yes, motor is moving. - lda #$28 anticipate error. + lda #MLI.E.NODEV anticipate error. dey no, dec retry counter bne .1 and try 256 times. .9 rts *-------------------------------------- -XRW.GetUnitIdx pha preserve acc across call - lda unitnum DSSS0000 - lsr - lsr - lsr - lsr - cmp #$08 - and #$07 - rol 0000SSSD - tay index to table. - pla restore acc - rts -*-------------------------------------- -* write subroutine (16 sector format) -* -* writes data from nbuf1 and buf. first nbuf2, high to low then direct -* from (buf), low to high. assumes 1 usec cycle time. self modified code !! -* -* on entry: x = slotnum times 16 -* -* on exit: carry set if error (write protect violation). -* if no error, acc=uncertain, x=unchanged, y=0, carry clear. -*-------------------------------------- -write16 sec anticipate write protect error - lda IO.D2.ReadProt,x - lda IO.D2.ReadMode,x sense write protect flag - bpl L580C - jmp wexit exit if write protected - -* timing is critical. a one micro-second cycle time is assumed. -* number in () is how many micro-seconds per instruction or subroutine - -L580C lda nbuf2 - sta pcl - lda #$FF sync data. - sta IO.D2.WriteMode,x (5) goto write mode - ora IO.D2.WShift,x (4) - ldy #$04 (2) for five nibls - nop (2) - pha (3) - pla (4) -wsync pha (3) exact timing. - pla (4) exact timing. - jsr wnibl7 (13,9,6) write sync. - dey (2) - bne wsync (3-) must not cross page ! - lda #$D5 (2) 1st data mark - jsr wnibl9 (15,9,6) - lda #$AA (2) 2nd data mark - jsr wnibl9 (15,9,6) - lda #$AD (2) 3rd data mark - jsr wnibl9 (15,9,6) - tya (2) zero checksum - ldy #$56 (2) nbuf2 index - bne L583D (3) branch always - -* total time in this write byte loop must = 32us !!! - -L583A lda nbuf2,y (4) prior 6-bit nibl -L583D eor nbuf2-1,y (5) xor with current - tax (2) index to 7-bit nibl - lda nibl,x (4) must not cross page boundary - ldx A2L (3) restore slot index - sta IO.D2.WLoad,x (5) store encoded byte - lda IO.D2.WShift,x (4) handshake - dey (2) - bne L583A (3-) must not cross page boundary - -* end of write byte loop - - lda pcl (3) get prior nibl (from nbuf2) -wrefd1 ldy #$00 (2) warning: load value modified by prenib. -wrefa1 eor $1000,y (4) warning: address modified by prenib. - and #$FC (2) strip low 2 bits - tax (2) index to nibl table - lda nibl,x (4) -wrefd2 ldx #$60 (2) warning: value modified by prenib. - sta IO.D2.WLoad,x (5) write nibl - lda IO.D2.WShift,x (4) handshake -wrefa2 lda $1000,y (4) prior nibl. warning: address modified by prenib. - iny (2) all done with this page ? - bne wrefa1 (3-) loop until page end. - lda pch (3) get next (precalculated & translated) nibl. - beq L58C0 (2+) branch if code written was page aligned. - lda A2H (3) get byte address of last byte to be written. - beq L58B3 (2+) branch if only 1 byte left to write. - lsr (2) test for odd or even last byte (carry set/clear) - lda pch (3) restore nibl to acc. - sta IO.D2.WLoad,x (5) - lda IO.D2.WShift,x (4) - lda A1L (3) = byte 0 of 2nd page xor'd with byte 1 if - nop (2) above test set carry. - iny (2) y=1 - bcs L5899 (2+) branch if last byte to be odd. -wrefa3 eor $1100,y (4) warning: address modified by prenib. - and #$FC (2) strip low 2 bits. - tax (2) index to nibl table - lda nibl,x (4) get nibl -wrefd3 ldx #$60 (2) restore slot index. warning: modified by prenib - sta IO.D2.WLoad,x (5) - lda IO.D2.WShift,x (4) -wrefa4 lda $1100,y (4) warning: modified by prenib - iny (2) got prior nibl, point to next -wrefa5 eor $1100,y (4) warning: modified by prenib -L5899 cpy A2H (3) set carry if this is the last nibl - and #$FC (2) strip low 2 bits - tax (2) - lda nibl,x (4) -wrefd4 ldx #$60 (2) restore slot. warning: modified by prenib - sta IO.D2.WLoad,x (5) - lda IO.D2.WShift,x (4) -wrefa6 lda $1100,y (4) get prior nibl. warning: modified by prenib - iny (2) - bcc wrefa3 (3-) branch if not the last. - bcs L58B1 (3) waste 3 cycles, branch always. -L58B1 bcs L58C0 (3) branch always. -L58B3 lda >pch (4) absolute reference to zero page - sta IO.D2.WLoad,x (5) - lda IO.D2.WShift,x (4) - pha (3) waste 14 micro-seconds total - pla (4) - pha (3) - pla (4) -L58C0 ldx A1H (3) use last nibl (anded with $FC) for checksum - lda nibl,x (4) -wrefd5 ldx #$60 (2) restore slot. warning: modified by prenib - sta IO.D2.WLoad,x (5) - lda IO.D2.WShift,x (4) - ldy #$00 (2) set y = index end mark table. - pha (3) waste another 11 micro-seconds - pla (4) - nop (2) - nop (2) -L58D3 lda endmrks,y (4) dm4, dm5, dm6 and turn off byte. - jsr wnibl (15,6) write it - iny (2) - cpy #$04 (2) have all end marks been written ? - bne L58D3 (3) if not. - clc (2,9) -wexit lda IO.D2.ReadMode,x out of write mode - lda IO.D2.WShift,x to read mode. - rts return from write. - -* 7-bit nibl write subroutines - -wnibl9 clc (2) 9 cycles, then write. -wnibl7 pha (3) 7 cycles, then write. - pla (4) -wnibl sta IO.D2.WLoad,x (5) nibl write - ora IO.D2.WShift,x (4) clobbers acc, not carry - rts (6) -*-------------------------------------- * preniblize subroutine (16 sector format) * * converts 256 bytes of user data in (buf) into 6 bit nibls in nbuf2. @@ -921,7 +355,7 @@ prn3 lda $10AC,y warning: self modified. get byte from highest group. eor (buf),y and #$FC tax - lda nibl,x get disk 7-bit nible equivalent. + lda XRW.FC2Nib,x get disk 7-bit nible equivalent. L595F sta pch beq L596F branch if data to be written is page aligned. @@ -938,24 +372,698 @@ L596F ldy #$FF index to last byte of data to write. lda (buf),y to be used as a checksum. and #$FC strip extra bits sta A1H and save it. + ldy buf+1 now modify address references to sty wrefa1+2 user data. sty wrefa2+2 + iny sty wrefa3+2 sty wrefa4+2 sty wrefa5+2 sty wrefa6+2 + ldx A2L and lastly, index references to stx wrefd2+1 controller. stx wrefd3+1 stx wrefd4+1 stx wrefd5+1 rts +*-------------------------------------- +* write subroutine (16 sector format) +* +* writes data from nbuf1 and buf. first nbuf2, high to low then direct +* from (buf), low to high. assumes 1 usec cycle time. self modified code !! +* +* on entry: x = slotnum times 16 +* +* on exit: carry set if error (write protect violation). +* if no error, acc=uncertain, x=unchanged, y=0, carry clear. +*-------------------------------------- +XRW.Write sec anticipate write protect error + lda IO.D2.ReadProt,x + lda IO.D2.ReadMode,x sense write protect flag + bpl L580C + + jmp wexit exit if write protected + +* timing is critical. a one micro-second cycle time is assumed. +* number in () is how many micro-seconds per instruction or subroutine + +L580C lda nbuf2 + sta pcl + + lda #$FF sync data. + sta IO.D2.WriteMode,x (5) goto write mode + ora IO.D2.WShift,x (4) + ldy #$04 (2) for five nibls + nop (2) + pha (3) + pla (4) + +wsync pha (3) exact timing. + pla (4) exact timing. + jsr wnibl7 (13,9,6) write sync. + dey (2) + bne wsync (3-) must not cross page ! + + lda #$D5 (2) 1st data mark + jsr wnibl9 (15,9,6) + lda #$AA (2) 2nd data mark + jsr wnibl9 (15,9,6) + lda #$AD (2) 3rd data mark + jsr wnibl9 (15,9,6) + tya (2) zero checksum + + ldy #$56 (2) nbuf2 index + bne L583D (3) branch always + +* total time in this write byte loop must = 32us !!! + +L583A lda nbuf2,y (4) prior 6-bit nibl +L583D eor nbuf2-1,y (5) xor with current + tax (2) index to 7-bit nibl + lda XRW.FC2Nib,x (4) must not cross page boundary + ldx A2L (3) restore slot index + sta IO.D2.WLoad,x (5) store encoded byte + lda IO.D2.WShift,x (4) handshake + dey (2) + bne L583A (3-) must not cross page boundary + +* end of write byte loop + + lda pcl (3) get prior nibl (from nbuf2) + +wrefd1 ldy #$00 (2) warning: load value modified by prenib. + +wrefa1 eor $1000,y (4) warning: address modified by prenib. + and #$FC (2) strip low 2 bits + tax (2) index to nibl table + lda XRW.FC2Nib,x (4) +wrefd2 ldx #$60 (2) warning: value modified by prenib. + sta IO.D2.WLoad,x (5) write nibl + lda IO.D2.WShift,x (4) handshake +wrefa2 lda $1000,y (4) prior nibl. warning: address modified by prenib. + iny (2) all done with this page ? + bne wrefa1 (3-) loop until page end. + + lda pch (3) get next (precalculated & translated) nibl. + beq L58C0 (2+) branch if code written was page aligned. + + lda A2H (3) get byte address of last byte to be written. + beq L58B3 (2+) branch if only 1 byte left to write. + + lsr (2) test for odd or even last byte (carry set/clear) + lda pch (3) restore nibl to acc. + sta IO.D2.WLoad,x (5) + lda IO.D2.WShift,x (4) + lda A1L (3) = byte 0 of 2nd page xor'd with byte 1 if + nop (2) above test set carry. + iny (2) y=1 + bcs L5899 (2+) branch if last byte to be odd. + +wrefa3 eor $1100,y (4) warning: address modified by prenib. + and #$FC (2) strip low 2 bits. + tax (2) index to nibl table + lda XRW.FC2Nib,x (4) get nibl +wrefd3 ldx #$60 (2) restore slot index. warning: modified by prenib + sta IO.D2.WLoad,x (5) + lda IO.D2.WShift,x (4) +wrefa4 lda $1100,y (4) warning: modified by prenib + iny (2) got prior nibl, point to next +wrefa5 eor $1100,y (4) warning: modified by prenib + +L5899 cpy A2H (3) set carry if this is the last nibl + and #$FC (2) strip low 2 bits + tax (2) + lda XRW.FC2Nib,x (4) +wrefd4 ldx #$60 (2) restore slot. warning: modified by prenib + sta IO.D2.WLoad,x (5) + lda IO.D2.WShift,x (4) +wrefa6 lda $1100,y (4) get prior nibl. warning: modified by prenib + iny (2) + bcc wrefa3 (3-) branch if not the last. + bcs L58B1 (3) waste 3 cycles, branch always. + +L58B1 bcs L58C0 (3) branch always. + +L58B3 lda >pch (4) absolute reference to zero page + sta IO.D2.WLoad,x (5) + lda IO.D2.WShift,x (4) + pha (3) waste 14 micro-seconds total + pla (4) + pha (3) + pla (4) + +L58C0 ldx A1H (3) use last nibl (anded with $FC) for checksum + lda XRW.FC2Nib,x (4) +wrefd5 ldx #$60 (2) restore slot. warning: modified by prenib + sta IO.D2.WLoad,x (5) + lda IO.D2.WShift,x (4) + + ldy #$00 (2) set y = index end mark table. + pha (3) waste another 11 micro-seconds + pla (4) + nop (2) + nop (2) + +L58D3 lda endmrks,y (4) dm4, dm5, dm6 and turn off byte. + jsr wnibl (15,6) write it + iny (2) + cpy #$04 (2) have all end marks been written ? + bne L58D3 (3) if not. + + clc (2,9) + +wexit lda IO.D2.ReadMode,x out of write mode + lda IO.D2.WShift,x to read mode. + rts return from write. + +* 7-bit nibl write subroutines + +wnibl9 clc (2) 9 cycles, then write. +wnibl7 pha (3) 7 cycles, then write. + pla (4) +wnibl sta IO.D2.WLoad,x (5) nibl write + ora IO.D2.WShift,x (4) clobbers acc, not carry + rts (6) +*-------------------------------------- +* delays a specified number of 100 usec intervals for motor timing. +* on entry: acc holds number of 100 usec intervals to delay. +* on exit: acc = 0, x = 0, y = unchanged, carry set. +* montimel, montimeh are incremented once per 100 usec interval +* for motor on timing. +*-------------------------------------- +XRW.Wait100ms lda #1 + +XRW.Wait100msA +.1 ldx #$11 delay 86 usec + +.2 dex + bne .2 + + inc montimel + bne .3 + + inc montimeh + +.3 sec + sbc #$01 + bne .1 + + rts +*-------------------------------------- +* read subroutine (16-sector format) +* +* reads encoded bytes into nbuf1 and nbuf2. +* first reads nbuf2 high to low, then nbuf1 low to high. +* on entry: x=slot# times $10, read mode +* on exit: carry set if error, else if no error: +* acc=$AA, x=unchanged, y=0, carry clear. +* observe 'no page cross' on some branches !! +*-------------------------------------- +XRW.Read txa get slot # + ora #$8C prepare mods to read routine. + sta rd4+1 warning: the read routine is + sta rd5+1 self modified !! + sta rd6+1 + sta rd7+1 + sta rd8+1 + + lda buf modify storage addresses also + ldy buf+1 + sta ref3+1 + sty ref3+2 + sec + sbc #$54 + bcs L571F branch if no borrow + + dey + +L571F sta ref2+1 + sty ref2+2 + sec + sbc #$57 + bcs L572B branch if no borrow + + dey + +L572B sta ref1+1 + sty ref1+2 + + ldy #$20 32 tries to find + +L5733 dey + beq L576D branch if can't find data header marks + +L5736 lda IO.D2.RData,x + bpl L5736 + +L573B eor #$D5 1st data mark + bne L5733 + + nop delay + +L5740 lda IO.D2.RData,x + bpl L5740 + + cmp #$AA 2nd data mark. + bne L573B if not, check for 1st again + + nop + +L574A lda IO.D2.RData,x + bpl L574A + + cmp #$AD 3rd data mark + bne L573B if not, check for data mark 1 again + + ldy #$AA + lda #$00 + +L5757 sta pcl use z-page for keeping checksum + +rd4 ldx IO.D2.RData+$60 warning: self modified + bpl rd4 + + lda XRW.Nib2FC-$96,x + sta nbuf2-$AA,y save the two-bit groups in nbuf. + eor pcl update checksum. + iny next position in nbuf. + bne L5757 loop for all $56 two-bit groups. + + ldy #$AA now read directly into user buffer. + bne rd5 always taken. + +L576D sec error + rts + +ref1 sta $1000,y warning: self modified + +rd5 ldx IO.D2.RData+$60 warning: self modified + bpl rd5 + + eor XRW.Nib2FC-$96,x get actual 6-bit data from dnib table. + ldx nbuf2-$AA,y get associated two-bit pattern + eor dnibl2,x and combine to form whole byte. + iny + bne ref1 loop for $56 bytes. + + pha save for now, no time to store... + and #$FC strip low bits. + ldy #$AA prepare for next $56 bytes + +rd6 ldx IO.D2.RData+$60 warning: self modified + bpl rd6 + + eor XRW.Nib2FC-$96,x + ldx nbuf2-$AA,y + eor dnibl3,x +ref2 sta $1000,y warning: self modified + iny + bne rd6 loop unil this group of $56 read + +rd7 ldx IO.D2.RData+$60 warning: self modified + bpl rd7 + + and #$FC + ldy #$AC last group is $54 long + +L57A5 eor XRW.Nib2FC-$96,x + ldx nbuf2-$AC,y + eor dnibl4,x combine to form full byte +ref3 sta $1000,y warning: self modified + +rd8 ldx IO.D2.RData+$60 warning: self modified + bpl rd8 + + iny + bne L57A5 + + and #$FC + eor XRW.Nib2FC-$96,x checksum ok ? + bne L57CC error if not. + + ldx A2L test end marks. + +L57C2 lda IO.D2.RData,x + bpl L57C2 + + cmp #$DE + + clc + beq L57CD branch if good trailer + +L57CC sec + +L57CD pla place last byte into user buffer + ldy #$55 + sta (buf),y + rts +*-------------------------------------- +* read address field subroutine (16-sector format) +* +* reads volume, track and sector. +* on entry: x = slot# times $10, read mode +* on exit: carry set if error, else if no error: +* acc=$AA, y=0, x=unchanged, carry clear, +* ccstv contains chksum,sector,track & volume read. +* uses temps: count,last,csum & 4 bytes at ccstv +* expects: original 10-sector normal density nibls (4-bit) odd bits then even. +* observe 'no page cross' warnings on some branches !!! +*-------------------------------------- +XRW.ReadAddr ldy #$FC + sty countn 'must find' count + + ldx A2L get slot # + +L569D iny + bne L56A5 low order of count. + + inc countn (2k nibles to find address mark + beq rderr else error) + +L56A5 lda IO.D2.RData,x read nibl + bpl L56A5 *** no page cross *** + +L56AA cmp #$D5 address mark 1 ? + bne L569D + + nop nibl delay + +L56AF lda IO.D2.RData,x + bpl L56AF *** no page cross *** + + cmp #$AA address mark 2 ? + bne L56AA if not, is it address mark 1 ? + + ldy #$03 index for 4 byte read + +L56BA lda IO.D2.RData,x + bpl L56BA *** no page cross *** + + cmp #$96 address mark 3 ? + bne L56AA if not, is it address mark 1 + + sei no interrupts until address is tested. + lda #$00 init checksum + +L56C6 sta csum + +L56C9 lda IO.D2.RData,x read 'odd bit' nibl + bpl L56C9 *** no page cross *** + + rol align odd bits, '1' into lsb. + sta last save them. + +L56D2 lda IO.D2.RData,x read 'even bit' nibl + bpl L56D2 *** no page cross *** + + and last merge odd and even bits. + sta XRW.AddrField,y store data byte. + eor csum + dey + bpl L56C6 loop on 4 data bytes. + + tay if final checksum non-zero, + bne rderr then error. + +L56E6 lda IO.D2.RData,x first bit-slip nibl + bpl L56E6 *** no page cross *** + + cmp #$DE + bne rderr + + nop delay + +L56F0 lda IO.D2.RData,x second bit-slip nible + bpl L56F0 *** no page cross *** + + cmp #$AA + bne rderr + + clc normal read ok + rts + +rderr sec + rts *-------------------------------------- .LIST ON -XRW.FREE .EQ $D700-* (2.0.3 = $02) +XRW.FREE1 .EQ $D4AA-* (2.0.3 = $02) .LIST OFF + .BS $D4AA-* +*-------------------------------------- +* nibl buffer 'nbuf2' must be at $xxAA +*-------------------------------------- +nbuf2 .BS $56 nibl buffer for read/write of low 2-bits of each byte. +*-------------------------------------- +* fast seek subroutine +* A = desired track +* curtrk = current 1/4 track +* +* montimel,h are incremented by the # of 100us quantums required by seek for motor on time overlap. +* variables used: curtrk, A2L, montimel, montimeh +*-------------------------------------- +XRW.Seek asl transform into 1/4 tracks + asl + + pha + + jsr XRW.GetUnitIdx get index to previous track + lda XRW.LastTrackPos,y for current drive. + + sta curtrk current position. + + pla + + sta XRW.LastTrackPos,y + +.1 lda XRW.LastTrackPos,y + + sec + sbc curtrk + beq .8 + + bcc .2 + + cmp #3 A>curtrk, must move in + bcc .3 + + lda #3 + bra .3 + +.2 cmp #$fe ADEBUG + + lda #$fe + +.3 tax save move direction + + clc + adc curtrk + sta curtrk + + jsr XRW.PhaseOn + + lda #28 + jsr XRW.Wait100msA Trash X + + jsr XRW.AllPhaseOff + + bra .1 + +.8 lsr curtrk convert back to track# + lsr curtrk + rts + +XRW.PhaseOn dex + bmi .1 + + pha + jsr .7 + pla + + bit #1 1,3,5,7 ? + beq .8 + + inc + bra .7 + +.1 bit #1 1,3,5,7 ? + beq .7 + + pha + inc + jsr .7 + pla + +.7 and #6 mask for 0,2,4,6 + ora A2L Slot $n0 + tax + lda IO.D2.Ph0On,x turn on one phase +.8 rts + +XRW.AllPhaseOff ldx A2L + lda IO.D2.Ph0Off,x make sure all motor phases are off. + lda IO.D2.Ph1Off,x + lda IO.D2.Ph2Off,x + lda IO.D2.Ph3Off,x + rts +*-------------------------------------- +XRW.LastTrackPos .EQ * +curtrk .HS 00 (D0S0) + .HS 00000000000000 for slots 1 thru 7 drive 1 +csum .HS 00 (D1S0) used for address header cksum + .HS 00000000000000 for slots 1 thru 7 drive 2 +*-------------------------------------- +XRW.ReqTrack .HS 00 +XRW.ReqSector .HS 00 +ibstat .HS 00 +XRW.LastUnitUsed .HS 00 +retrycnt .HS 00 +seekcnt .HS 00 +countn .EQ * 'must find' count. +last .HS 00 'odd bit' nibls. + +XRW.AddrField .HS 00 AddrField Checksum +XRW.AddrField.S .HS 00 AddrField Sector +XRW.AddrField.T .EQ * AddrField Track +montimel .HS 00 +XRW.AddrField.V .EQ * AddrField Volume +montimeh .HS 00 +*-------------------------------------- + .LIST ON +XRW.FREE2 .EQ $D596-* + .LIST OFF + .BS $D596-* +*-------------------------------------- +* 7-bit to 6-bit 'deniblize' table (16-sector format) +* +* valid codes are $96 to $FF only. codes with more than one pair of +* adjacent zeroes or with no adjacent ones (except bit 7) are excluded. +* +* nibbles in the ranges of $A0-$A3, $C0-$C7, $E0-$E3 are used for +* other tables since no valid nibbles are in these ranges. +* aligned to page boundary + $96 +*-------------------------------------- +XRW.Nib2FC .HS 0004 + .HS FFFF + .HS 080C + .HS FF + .HS 101418 +twobit3 .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 +twobit2 .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 +twobit1 .HS 0008040C used in fast prenib. + .HS FF + .HS A4A8AC + .HS FF + .HS B0B4B8BCC0C4C8 + .HS FFFF + .HS CCD0D4D8DCE0 + .HS FF + .HS E4E8ECF0F4F8FC +*-------------------------------------- +* 6-bit to 2-bit conversion tables: +* +* origin = $D600 (page boundary) +* +* dnibl2 abcdef-->0000FE +* dnibl3 abcdef-->0000DC +* dnibl4 abcdef-->0000BA +* page align the following tables: +*-------------------------------------- +* FC-bits to nibble conversion table (256 bytes) +* +* codes with more than one pair of adjacent zeroes +* or with no adjacent ones (except B7) are excluded. +*-------------------------------------- +dnibl2 .HS 00 +dnibl3 .HS 00 +dnibl4 .HS 00 +XRW.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 *-------------------------------------- XRW.LEN .EQ *-XRW.START MAN