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 bae372a..4bf263d 100644 Binary files a/SOFTCARD80.BIN#041000 and b/SOFTCARD80.BIN#041000 differ diff --git a/zapple2.po b/zapple2.po index 8b8304b..baed252 100644 Binary files a/zapple2.po and b/zapple2.po differ