From 21733742430666e14525b7caafe7416d94e2f8c8 Mon Sep 17 00:00:00 2001 From: Bobbi Webber-Manners Date: Sun, 20 Oct 2019 21:41:04 -0400 Subject: [PATCH] F_OPEN now seeks to & updates sequential record # --- SOFTCARD80.ASM#040000 | 113 +++++++++++++++++++++++++++++++++--------- SOFTCARD80.BIN#041000 | Bin 32771 -> 32771 bytes zapple2.po | Bin 819200 -> 819200 bytes 3 files changed, 89 insertions(+), 24 deletions(-) diff --git a/SOFTCARD80.ASM#040000 b/SOFTCARD80.ASM#040000 index da7cf5b..b352a18 100644 --- a/SOFTCARD80.ASM#040000 +++ b/SOFTCARD80.ASM#040000 @@ -830,28 +830,19 @@ _F_OPEN LD IX,PATHBUF ; Destination buffer LD (HL),A ; Store file reference number in S2 field PUSH HL ; Keep pointer into FCB for later - ; ProDOS GET_EOF call. Convert bytes to records (ie: divide by 128) + ; ProDOS GET_EOF call ; Assumes no files > 64K on ProDOS filesystem LD (FO2MLIN),A ; Store file ref num in param list LD HL,FO2MLI ; Pass address of 6502 JSR instruction CALL PRODOS ; Invoke ProDOS MLI (GET_EOF) - LD A,(FO2MLIE2) ; Most significant byte of length - SLA A ; Max file size per extent is 16K: 128*128 - LD B,A ; Stash in B for now - LD A,(FO2MLIE1) ; Least significant byte of length - AND 80H ; Keep most significant bit, mask off others - SRA A ; Move to LSB (shift seven times) - SRA A ; ... - SRA A ; ... - SRA A ; ... - SRA A ; ... - SRA A ; ... - SRA A ; ... - OR B ; Leaves file length in records in A + + ; Convert length in bytes to length in records + LD HL,(FO2MLIE2) ; Load 16 bit length + CALL LEN2RECS ; Leaves number of records in A ; Store records used POP HL ; Recover pointer into FCB - INC HL ; Advance to records used field + INC HL ; Advance to records used (offset 0FH) LD (HL),A ; Set records used ; Set sequential record number to zero @@ -1024,7 +1015,6 @@ FSNS2 LD A,0FFH ; No match RET ; FCB used for opening ProDOS directory corresponding to drive -; We only need the first 16 bytes (no need for allocation map) DFCB ; File control block for directory DFCBDRV DEFB 00H ; FCB Drive (0 current, 1 A:, 2 B: etc) DFCBNAM DEFM ' ' ; FCB filename and extension (all spaces) @@ -1032,6 +1022,9 @@ DFCBEX DEFB 00H ; FCB extent field DFCBS1 DEFB 00H ; FCB S1 field DFCBS2 DEFB 00H ; FCB S2 field DFCBRC DEFB 00H ; FCB RC field +DFCBMAP DEFS 16 ; Map of blocks in file +DFCBSR DEFB 0 ; FCB seq record number +DFCBRR DEFB 0,0,0 ; FCB rand record number ; Delete file ; DE is the address of the FCB describing the file to delete @@ -1062,40 +1055,77 @@ FDMLIP DEFW PATHBUF+OFFSET ; ProDOS PL: Pointer to path in 6502 addr ; DE is the address of the FCB describing the file from which to read ; Returns error codes in A and L: ; 0 OK, 1 EOF, 9 invalid FCB, 10 media changed, 0FFH h/w error -; TODO: Use Sequential Record field of FCB to determine from where to begin -; reading. Increment it so next read advances to next record. -F_READ LD H,D ; Pointer to FCB ... +F_READ PUSH DE ; Preserve pointer to FCB + LD H,D ; Pointer to FCB ... LD L,E ; ... into HL LD BC,0EH ; Offset to S2 field (reserved field) ADD HL,BC ; Compute address LD A,(HL) ; Obtain file reference num from FCB S2 - LD (FR2MLIN),A ; Store in parameter list + LD (FRMLIN),A ; Store in parameter list for SET_MARK + LD (FR2MLIN),A ; Store in parameter list for READ + + LD BC,20H-0EH ; Skip ahead to seq record num in FCB + ADD HL,BC ; ... + LD A,(HL) ; Obtain sequential record number + CALL RECS2LEN ; Leaves the length in bytes in HL + LD (FRMLIP1),HL ; Write 16 bit length in FRMLIP1,FRMLIP2 + XOR A ; Set FRMLIP3 to zero + LD (FRMLIP3),A ; ... + LD HL,FRMLI ; Pass address of 6502 JSR instruction + CALL PRODOS ; Invoke ProDOS MLI - SET_MARK + CP 4DH ; See if position was out of range + JP Z,FRBFCB ; If so, return invalid FCB code (9) + CP 43H ; See if it was a bad file ref number + JP Z,FRBFCB ; If so, return invalid FCB code (9) + CP 0 ; See if there was some other error + JP NZ,FRERR ; If so, return code 0FFH (h/w error) LD HL,(DMAADDR) ; Read from DMA buffer address LD BC,OFFSET ; Convert to 6502 address ADD HL,BC ; ... LD (FR2MLIDB),HL ; Store I/O buffer address in parm list LD HL,FR2MLI ; Pass address of 6502 JSR instruction - CALL PRODOS ; Invoke ProDOS MLI + CALL PRODOS ; Invoke ProDOS MLI - READ CP 4CH ; See if it was EOF JP Z,FREOF ; If so, return EOF code (1) CP 43H ; See if it was a bad file ref number JP Z,FRBFCB ; If so, return invalid FCB code (9) CP 0 ; See if there was some other error JP NZ,FRERR ; If so, return code 0FFH (h/w error) + + POP DE ; Get pointer to FCB back + LD H,D ; Pointer to FCB ... + LD L,E ; ... into HL + LD BC,20H ; Advance to sequential rec number field + ADD HL,BC ; ... + INC (HL) ; Increment sequential record number + XOR A ; Zero for success LD L,A ; Return code in L also RET ; Done -FREOF LD A,1 ; EOF return code +FREOF POP DE ; Fix up stack + LD A,1 ; EOF return code LD L,A ; Return code in L also RET ; Done (EOF) -FRBFCB LD A,9 ; Invalid FCB return code +FRBFCB POP DE ; Fix up stack + LD A,9 ; Invalid FCB return code LD L,A ; Return code in L also RET ; Done (EOF) -FRERR LD A,0FFH ; All other errors are 0FFH +FRERR POP DE ; Fix up stack + LD A,0FFH ; All other errors are 0FFH LD L,A ; Return code in L aslo RET ; Done (error) +FRMLI DEFB 20H,00H,0BFH ; JSR $BF00 in 6502 code + DEFB 0CEH ; ProDOS SET_MARK call + DEFW FRMLIPL+OFFSET ; Pointer to parm list in 6502 addr space + DEFB 60H ; RTS in 6502 code +FRMLIPL DEFB 2 ; ProDOS PL: Two parameters +FRMLIN DEFB 0 ; ProDOS PL: File reference number +FRMLIP1 DEFB 0 ; ProDOS PL: Position (LSB) +FRMLIP2 DEFB 0 ; ProDOS PL: Position +FRMLIP3 DEFB 0 ; ProDOS PL: Position (MSB) + FR2MLI DEFB 20H,00H,0BFH ; JSR $BF00 in 6502 code DEFB 0CAH ; ProDOS READ call DEFW FR2MLIPL+OFFSET ; Pointer to parm list in 6502 addr space @@ -1689,6 +1719,41 @@ GIOAS4 LD HL,IOBUF4 ; Address of I/O buf 4 -> HL LD A,4 ; FRN slot 4 RET +; Convert length in bytes to the number of 128 byte records +; Length in bytes is passed in HL +; Length in records is returned in A +; TODO This function returns one record more than it should if length is an +; exact multiple of 128 +LEN2RECS LD A,H ; Most significant byte of length + SLA A ; Shift left to make space + LD B,A ; Stash in B for now + LD A,L ; Least significant byte of length + AND 80H ; Keep most significant bit, mask off others + SRA A ; Move to LSB (shift seven times) + SRA A ; ... + SRA A ; ... + SRA A ; ... + SRA A ; ... + SRA A ; ... + SRA A ; ... + OR B ; Leaves file length in records in A + INC A ; Round up + RET + +; Convert number of 128 byte records to length in bytes +; Length in records is passed in A +; Returns the length in bytes in HL +RECS2LEN LD L,A ; A->HL + LD H,0 ; ... + ADD HL,HL ; Shift left seven times + ADD HL,HL ; ... + ADD HL,HL ; ... + ADD HL,HL ; ... + ADD HL,HL ; ... + ADD HL,HL ; ... + ADD HL,HL ; ... + RET + ; Convert value in HL into an HEX ASCII string, pointed to by DE ; Courtesy of http://map.grauw.nl/sources/external/z80bits.html#5.2 ; Trashes A diff --git a/SOFTCARD80.BIN#041000 b/SOFTCARD80.BIN#041000 index bae372a585e49ab182fd6a4fa78a013e72c90ea8..4bf263d4893da5dbb76f2e4bb8123dd3b4dea34c 100644 GIT binary patch delta 1394 zcmZ8hTWs4@7(Py;Ebb+}MC!J5+TvJh)wHaY#S2y!kSeWI0`UMuXn=5z?USsN=z1fW z)-{nTZ7(3L3Zf51LR=>Kf*Ua}x6_`K6rFpFBu?@Wvy+*`U;wZ|Xu^bM^`?nq5rHif$ z3U97#I7~C%*s&-EJ%qkRGL>`B*PW_i3o06D#rcy6h_)r!!ndw06oOvJ_ z`AF7;Ph@V%@q5--knLf*q2fDov=cdJQOL^NIYC zx8fEYR7@?gS@QS$r=?x-ObOyK@YK5$SL#j{x0r%F+7SD~t8n|cBXy3rLW8cLIyT)E>y#)S`(n$XUPCkIN34RECFRSp?#0SF8cT@4F{F1sa`%vxhwv=k> z-IqI2u)ci$(gSK-gTa7-h;$-zke=mBgaV19JAmp=AThShLMt61v5hJqdJs7I01DYp z8WZI3rQ$3JX8Gn=(>FyzG&)>R(0VHj)w`rtF~3#IRS>U{GM&KpfJE1H7(Ez3GfVtT zk29tK48f%O!Nj10X}1*5xu$SkM#P(`OU7SByanPO5pRQdNW?oJ82FdeIh4OZb{|~n k89B9{TN&8?D-7x5-Kf`H`mFgxa@IVQJOy(31~K;h2ZP2=x&QzG delta 1281 zcmZ8h-D@0G6u*-!+ufwiMw|BLo9XUxp!ka zD@D-O-(@j^O#9nu$mMv~u+KMUyog#gy%ielx;z%gF^78M>0!*Dz}^lCkj3MQBx3vl z*M;JGU3?kyFR&G96mJe@r4hVU+#GuHF4qLz;CfNq)TMFEFKAJ8E)EE~IqOtdULdvs z#M&D=LI@@m>7v{Qp9nRRECtBTVeu;FFSjTZuyhqSDHiq+O}*)DGTavIub;Adt4VR@ z5$=72y@~Ms-8B35RH)@H<_(QIiQ?&HYKqrsrS4%`gM4?e{UtU5$EjwPsdSx&3l&(| z2{FRxe-1?3Zs`F|7@#9)msVP0@+Xw0aB1Z+v7b-P$y}qwcuD+7$s|yy^96<1Lig9) zDJ3}L$_lU~3M+|&C;k}0ot={-AW?B&Ch=AXlVtm~uJC4vbH@Ej2`1fd7|xASO?k?= zxgWU4@b?zO`-*2y?}>N!!JK@kq1%vvg9kOs>L;xrpFgdE;yoz-)_G_dK1G^U_LF`6 zt@OOy*3eJqGslp_`mNh}_{y6J^Wxkg(zaqIW?9K+TDew zbA)+MLHvI@a<*aTx{!H67=hSNRG0}}1L3sOT2;4~wz|(fd^dseN25sSD+Fkx^p_el zZmUNlN9?avw$#_UqA`1&#n+)bp)1n~W0ofPwQ20QLWTq7@!q)3}gUtOb7ZOPJuT; zW87ePR=_X<$0Y_XpR>~u9I>>fD>O=0%4zFvnMyhgH>s3|;Wm{DFj&lqN2Lbs@AQ77 Tm%KmdWf<39nsJYKmH>siZAcT^($aQX+71m) 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 GOaB1ScHu|> delta 2357 zcmZWq4{Q_H8GmOx_PzI%$rKp;+hC+CiK$Y4~snkDnnryj{R-v<@i=DYrC>f}o2N_Dz4$&3WLR+^ud*^>a z>`vdkd*Azg|G)3f=i_}oeqeQ0{vmMT8rW0Hdq;a8)^lcPq4l7^C&l8#aqB|RmBGHPT8ou?VinX|{(7E)1)&J1_6;~My6^%Fb! zA6M_KBf8`49}JDvPwi;jxm_7P&Thm?RuB6MqrCqcwn2Ng7dDanc3qiL_6j?zL(e%P zvup{y|x07k+N5&^o>Fm8&Yuc=4IG)_A_{1nS7Pi=B!x1;Pmra!0Q0-1AM20cRTnl z2k#+8S7FWCZNiH}P|({e>~8y*{kFYSTqCX*9}_L2EcRM|DYnvQueDFSD*jzmdago- z@!l0f9Jm;HwB5>pBk{Z|@7QWBIxze705#zczGtI>g(5EsQB&+-L?=!8BfWBbA#4)( zDuDrcu%tpTtr8-4#W)Cl82+uG%0J>-RO2PC4^~AD8m?*8aY!+sH6YK832d2$# zFOv_T-)*T9OottM&;Y3hx8E6>RP9p7#;If4m>U2qKMNe9z-9}rd9T2=1S}t&;Iymhn0z?T<+$dwU-xwM55d5CPxBZA3k7@Zx37T)J@T@#>7y9 z84Y1)hgC;&1%M=kA@c|(=J|5xp>tc z@!Qhr`{+i8)ev(BsRf1-NXE5XObJCz8~d+AjdK1o_FgC~Gm7j@L_MK)E(!-brS1|qj0UnM%}<@j+%q( zB$gfo8YOeEPTKl?l^r$ffeP-F*si!Xd^ic#sptb#e%=j2w`qlQfWOVWnaVyd(VaPm zOKfrAlytj$Hn-u<(*>Ywi5{4jdg5T5d^HDI?}yS7U3RcvQqPvAE=|lqRN%GB(q}VkzX;>Kw(h z1CAt=HdL*p(=ierkS%Vy49k`-x_l^GJah@DAQK?5FW_<mQ0)`U@$h8TZ`{+X6l>iy_#4f#5Z^tq`odv&YGJtwt0m4$4?yryY(k(+~P z1^M0}+Le|{DMF zw_oC%tt}p|Rgy%`<&bDl?Hw*|{bQWqaY-HA>Q-m+Om?<&ww4yB-R5d`wsMDT&z6zG zi)fbYzld^3&Lz~KOkYC#b>!3kpqjMnga-ULSrHt z%;`K$kh~N@5}DFro_sQa4iM)6VwIk6Q6Yoq|1bS-dtHxr>l$}9)R3HcB$HF~=oxbF zW0XriH{d36B96B7wcrx+MI0UMyN4ek?F;B}&5j?E-Pvd*@j#r-G?J4LSLqv{tlzbF zdy;>X!C#W6wYcH`eAX+QbXdr=0iovG`aeNyiD@3yD?c~jy2alvt@XpiH-w6nxh42~ zb|%X&ad<;!lLi^crXiHC{F}q&TIH{+@FRFwz;lbmyyL(((n89WW*js0^SDC!xDDUT zc%!`Q!uxa?6zjq7WeTl)a1`%khF`${U4&~+;)^