F_READ and F_WRITE seem to be somewhat working.

This commit is contained in:
Bobbi Webber-Manners 2019-10-16 17:29:56 -04:00
parent 596118dbac
commit d99a6b6cf4
3 changed files with 269 additions and 99 deletions

View File

@ -60,9 +60,10 @@ RVEC7 DEFW 0000H ; Restart vector 7
DMAADDR DEFW 0080H ; DMA address defaults to FILEBUF (0080H)
LOGVEC DEFW 0000H ; Vector of logged in drives
ROVEC DEFW 0000H ; Vector of read-only drives
USERNUM DEFB 00H ; User number
USERNUM DEFB 00H ; User number TODO: This goes elsewhere
; End of private, implementation dependent space
;TODO: There are two FCBS and the address here is wrong
ORG 0060H ; Standard addr of 32 byte FCB
FCB1 ; File control block #1
FCB1DRV DEFB 00H ; FCB Drive (0 current, 1 A:, 2 B: etc)
@ -85,37 +86,35 @@ FILEBUF DEFS 128 ; Command args go here too (Pascal string)
; Print signon message using C_WRITESTR
PROGSTRT LD DE,WELCOME ; Address of string
LD C,09H ; C_WRITESTR call
CALL BDOS ; CP/M BDOS call
LD C,B_C_WRTSTR ;
CALL BDOS ;
; Print the alphabet using C_WRITE
LD B,'A'
LD B,'A' ; First character
L1 LD E,B ; Character to print
LD C,02H ; C_WRITE call
LD C,B_C_WRITE ;
PUSH BC ; Preserve B (and C)
CALL BDOS ; CP/M BDOS call
CALL BDOS ;
POP BC ; Restore B (and C)
INC B
LD A,'Z'
CP B
JP Z,S1
JP L1
INC B ;
LD A,'Z' ; Last character
CP B ;
JP Z,S1 ;
JP L1 ;
; Loop until there is a keystroke waiting using C_STAT
S1 LD C,0BH ; C_STAT call
CALL BDOS ; CP/M BDOS call
S1 LD C,B_C_STAT ;
CALL BDOS ;
CP 0 ; Anything?
JR Z,S1 ; If not, loop
; Print a couple of asterisks
LD E,'*' ;
LD C,02H ; C_WRITE call
CALL BDOS ; CP/M BDOS call
LD C,B_C_WRITE ;
CALL BDOS ;
LD E,'*' ;
LD C,2 ; C_WRITE call
CALL BDOS ; CP/M BDOS call
LD C,B_C_WRITE ;
CALL BDOS ;
; Create an FCB
LD A,1 ; A: drive
@ -143,62 +142,104 @@ S1 LD C,0BH ; C_STAT call
LD A,'P' ; Extension
LD (FCB1NAM+10),A ;
; Create a file using ProDOS MLI
; Create and open a file using ProDOS MLI
; Creates 'A/TESTFILE.TMP'
; Directory 'A' needs to exist already
LD DE,CMSG ; Address of string
LD C,09H ; C_WRITESTR call
CALL BDOS ; CP/M BDOS call
LD C,B_C_WRTSTR ;
CALL BDOS ;
LD DE,FCB1 ; Default FCB address
LD C,16H ; F_MAKE call
CALL BDOS ; CP/M BDOS call
LD C,B_F_MAKE ;
CALL BDOS ;
CALL CHECKOK
; Open the file just created
; Write to the file (two 128 byte records)
LD DE,OMSG ; Address of string
LD C,09H ; C_WRITESTR call
CALL BDOS ; CP/M BDOS call
LD DE,WMSG ; Address of string
LD C,B_C_WRTSTR ;
CALL BDOS ;
LD DE,FCB1 ; Default FCB address
LD C,0FH ; F_OPEN call
CALL BDOS ; CP/M BDOS call
LD C,B_F_WRITE ;
CALL BDOS ;
CALL CHECKOK
LD DE,FCB1 ; Default FCB address
LD C,B_F_WRITE ;
CALL BDOS ;
CALL CHECKOK
; Close the file
LD DE,CLMSG ; Address of string
LD C,09H ; C_WRITESTR call
CALL BDOS ; CP/M BDOS call
LD C,B_C_WRTSTR ;
CALL BDOS ;
LD DE,FCB1 ; Default FCB address
LD C,10H ; F_CLOSE call
CALL BDOS ; CP/M BDOS call
LD C,B_F_CLOSE ;
CALL BDOS ;
CALL CHECKOK
; Open the file
LD DE,OMSG ; Address of string
LD C,B_C_WRTSTR ;
CALL BDOS ;
LD DE,FCB1 ; Default FCB address
LD C,B_F_OPEN ;
CALL BDOS ;
CALL CHECKOK
; Read from the file
LD DE,RMSG ; Address of string
LD C,B_C_WRTSTR ;
CALL BDOS ;
LD DE,FCB1 ; Default FCB address
LD C,B_F_READ ;
CALL BDOS ;
CALL CHECKOK
; Close the file
LD DE,CLMSG ; Address of string
LD C,B_C_WRTSTR ;
CALL BDOS ;
LD DE,FCB1 ; Default FCB address
LD C,B_F_CLOSE ;
CALL BDOS ;
CALL CHECKOK
; Delete the file
LD DE,DMSG ; Address of string
LD C,09H ; C_WRITESTR call
CALL BDOS ; CP/M BDOS call
LD DE,FCB1 ; Default FCB address
LD C,13H ; F_DELETE call
CALL BDOS ; CP/M BDOS call
CALL CHECKOK
; LD DE,DMSG ; Address of string
; LD C,B_C_WRTSTR ;
; CALL BDOS ;
;
; LD DE,FCB1 ; Default FCB address
; LD C,B_F_DELETE ;
; CALL BDOS ;
;
; CALL CHECKOK
; Read keyboard and echo to screen C_READ, C_WRITE
L2 LD C,1 ; C_READ call
CALL BDOS ; CP/M BDOS call
L2 LD C,B_C_READ ;
CALL BDOS ;
LD E,A ; Prepare to echo keystroke
LD C,2 ; C_WRITE call
CALL BDOS ; CP/M BDOS call
LD C,B_C_WRITE ;
CALL BDOS ;
JP L2 ; Forever and ever
; Check an MLI call was successful and print out message accordingly
@ -206,8 +247,8 @@ CHECKOK LD A,(AREG) ; Look at the return code
CP 0 ; Success?
JP Z,SUCC ;
LD DE,FAILMSG1 ; Fail message
LD C,09H ; C_WRITESTR call
CALL BDOS ; CP/M BDOS call
LD C,B_C_WRTSTR ;
CALL BDOS ;
LD L,A ; Copy to HL for NUM2HEX
LD H,0 ; ...
LD DE,HEXBUF ; Generate hex string to HEXBUF
@ -215,15 +256,15 @@ CHECKOK LD A,(AREG) ; Look at the return code
LD A,0FFH ; 0FFH for error
LD L,A ; Return code in L also
LD DE,HEXBUF+2 ; Write hex value to console
LD C,09H ; C_WRITESTR call
CALL BDOS ; CP/M BDOS call
LD C,B_C_WRTSTR ;
CALL BDOS ;
LD DE,FAILMSG2 ; Fail message
LD C,09H ; C_WRITESTR call
CALL BDOS ; CP/M BDOS call
LD C,B_C_WRTSTR ;
CALL BDOS ;
RET ;
SUCC LD DE,SUCCMSG ; Success message
LD C,09H ; C_WRITESTR call
CALL BDOS ; CP/M BDOS call
LD C,B_C_WRTSTR ;
CALL BDOS ;
RET
WELCOME DEFB 13
@ -231,15 +272,23 @@ WELCOME DEFB 13
DEFB 13, '$'
CMSG DEFB 13
DEFM 'Creating A/TESTFILE.TMP'
DEFM 'Creating & opening A/TESTFILE.TMP'
DEFB 13, '$'
WMSG DEFB 13
DEFM 'Writing record to A/TESTFILE.TMP'
DEFB 13, '$'
CLMSG DEFB 13
DEFM 'Closing A/TESTFILE.TMP'
DEFB 13, '$'
OMSG DEFB 13
DEFM 'Opening A/TESTFILE.TMP'
DEFB 13, '$'
CLMSG DEFB 13
DEFM 'Closing A/TESTFILE.TMP'
RMSG DEFB 13
DEFM 'Reading record from A/TESTFILE.TMP'
DEFB 13, '$'
DMSG DEFB 13
@ -256,28 +305,31 @@ FAILMSG2 DEFM ')'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Implementation of CP/M STYLE BDOS
; Function to invoke is passed in C
; C=00H C_TERMCPM System reset
; C=01H C_READ Console read
; C=02H C_WRITE Console write
; C=07H GET_IOB Get IOBYTE
; C=08H SET_IOB Set IOBYTE
; C=09H C_WRITESTR Console write string
; C=0BH C_STAT Console status
; C=0CH S_BDOSVER Return version number
; C=0DH DRV_ALLRESET Reset disks
; C=0EH DRV_SET Select disk
; C=0FH F_OPEN Open file
; C=10H F_CLOSE Close file (IN PROGRESS)
; C=13H F_DELETE Delete file
; C=16H F_MAKE Create file (IN PROGRESS)
; C=17H DRV_LOGVEC Return bitmap of logged-in drives
; C=19H DRV_GET Return current drive
; C=1AH F_DMAOFF Set DMA address
; C=1CH DRV_SETRO Software write-protect current drive
; C=1DH DRV_ROVEC Return bitmap of read-only drives
; C=20H F_USERNUM Get/set user number
; C=25H DRV_RESET Selectively reset disk drives
; Function to invoke is passed in C, as follows:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
B_C_TERMCPM EQU 00H ; System reset
B_C_READ EQU 01H ; Console read
B_C_WRITE EQU 02H ; Console write
B_GET_IOB EQU 07H ; Get IOBYTE
B_SET_IOB EQU 08H ; Set IOBYTE
B_C_WRTSTR EQU 09H ; Console write string
B_C_STAT EQU 0BH ; Console status
B_S_BDOSVER EQU 0CH ; Return version number
B_DRV_ALLRST EQU 0DH ; Reset disks
B_DRV_SET EQU 0EH ; Select disk
B_F_OPEN EQU 0FH ; Open file
B_F_CLOSE EQU 10H ; Close file
B_F_DELETE EQU 13H ; Delete file
B_F_READ EQU 14H ; Read file
B_F_WRITE EQU 15H ; Write file
B_F_MAKE EQU 16H ; Create and open file
B_DRV_LOGVEC EQU 17H ; Return bitmap of logged-in drives
B_DRV_GET EQU 19H ; Return current drive
B_F_DMAOFF EQU 1AH ; Set DMA address
B_DRV_SRO EQU 1CH ; Software write-protect current drive
B_DRV_ROVEC EQU 1DH ; Return bitmap of read-only drives
B_F_USERNUM EQU 20H ; Get/set user number
B_DRV_RESET EQU 25H ; Selectively reset disk drives
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ORG BDOSADDR
@ -286,6 +338,7 @@ BDOSINIT LD SP,STCKTOP ; Initialize SP
LD A,0 ;
LD (IOBYTE),A ; Initialize IOBYTE
LD (CURDRV),A ; Drive A:
LD (FILEBUF),A ; Zero chars in command tail
LD (FRN1),A ; Initialize FRNs to zero
LD (FRN2),A ; ...
LD (FRN3),A ; ...
@ -330,8 +383,8 @@ BDOSVEC DEFW C_TERMCPM ; C=00H
DEFW UNIMP ; C=11H (F_SFIRST)
DEFW UNIMP ; C=12H (F_SNEXT)
DEFW F_DELETE ; C=13H
DEFW UNIMP ; C=14H (F_READ)
DEFW UNIMP ; C=15H (F_WRITE)
DEFW F_READ ; C=14H
DEFW F_WRITE ; C=15H
DEFW F_MAKE ; C=16H
DEFW UNIMP ; C=17H (F_RENAME)
DEFW DRV_LOGVEC ; C=18H
@ -520,17 +573,17 @@ FOS5 LD (FOIOB),A ; Record the buffer index in local var
CP 3 ; Is it 3? ...
JP Z,FOS8 ; ... yes
JP FOS9 ; Must be 4
FOS6 LD A,(FOMLIN) ;
LD (FRN1),A ;
FOS6 LD A,(FOMLIN) ; IOBUF1: Store file ref number in FRN1
LD (FRN1),A ; ...
JP FOS10 ;
FOS7 LD A,(FOMLIN) ;
LD (FRN2),A ;
FOS7 LD A,(FOMLIN) ; IOBUF2: Store file ref number in FRN2
LD (FRN2),A ; ...
JP FOS10 ;
FOS8 LD A,(FOMLIN) ;
LD (FRN3),A ;
FOS8 LD A,(FOMLIN) ; IOBUF3: Store file ref number in FRN3
LD (FRN3),A ; ...
JP FOS10 ;
FOS9 LD A,(FOMLIN) ;
LD (FRN4),A ;
FOS9 LD A,(FOMLIN) ; IOBUF4: Store file ref number in FRN4
LD (FRN4),A ; ...
JP FOS10 ;
FOS10 LD A,0 ; Success
LD L,A ; Copy to L
@ -553,16 +606,21 @@ FOIOB DEFB 0 ; Local variable to record IOBUF idx
; Close file
; DE is the address of the FCB describing the file to close
; Returns error codes in A and L:
F_CLOSE
LD H,D ; Pointer to FCB ...
F_CLOSE LD H,D ; Pointer to FCB ...
LD L,E ; ... into HL
LD BC,14 ; Offset to S2 field (reserved field)
ADD HL,BC ; Compute address
LD A,(HL) ; Obtain file reference num from FCB S2
LD (FCMLIN),A ; Store in parameter list
LD HL,FCMLI ; Pass address of 6502 JSR instruction
CALL PRODOS ; Invoke ProDOS MLI
CP 0 ; See if there was an error
JP NZ,FCERR ; Handle error
;
; TODO - SET THE APPROPRIATE FRN[1234] TO ZERO TO FREE BUFFER
;
LD L,A ; Return in L also
RET
FCERR LD A,0FFH ; 0FFH for error
@ -597,6 +655,87 @@ FDMLI DEFB 20H,00H,0BFH ; JSR $BF00 in 6502 code
FDMLIPL DEFB 1 ; ProDOS PL: Seven parameters
FDMLIP DEFW PATHLEN+OFFSET ; ProDOS PL: Pointer to path in 6502 addr
; Read next record
; 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
F_READ LD H,D ; Pointer to FCB ...
LD L,E ; ... into HL
LD BC,14 ; Offset to S2 field (reserved field)
ADD HL,BC ; Compute address
LD A,(HL) ; Obtain file reference num from FCB S2
LD (FRMLIN),A ; Store in parameter list
CALL GETIOADDR ; Get I/O address
CP 0FFH ; See if it was an error
JP Z,FRERR ; If so, abort
LD BC,OFFSET ; Convert to 6502 address
ADD HL,BC ; ...
LD (FRMLIDB),HL ; Store I/O buffer address in parm list
LD HL,FRMLI ; Pass address of 6502 JSR instruction
CALL PRODOS ; Invoke ProDOS MLI
CP 0 ; See if there was an error
JP NZ,FRERR ; Handle error
LD L,A ; Return code in L also
RET ; Done
FRERR LD A,0FFH ; TODO: All errors are 0FFH for now
LD L,A ; Return code in L aslo
RET ; Done (error)
FRMLI DEFB 20H,00H,0BFH ; JSR $BF00 in 6502 code
DEFB 0CAH ; ProDOS READ call
DEFW FRMLIPL+OFFSET ; Pointer to parm list in 6502 addr space
DEFB 60H ; RTS in 6502 code
FRMLIPL DEFB 4 ; ProDOS PL: Four parameters
FRMLIN DEFB 0 ; ProDOS PL: File reference number
FRMLIDB DEFW 0000H ; ProDOS PL: Data buffer
FRMLIRC DEFW 128 ; ProDOS PL: Request count (bytes to read)
FRMLITC DEFW 0000H ; ProDOS PL: Number of bytes transferred
; Write next record
; DE is the address of the FCB describing the file to which to write
; Returns error codes in A and L:
; 0 OK, 1 dir full, 2 disk full, 9 invalid FCB, 10 media changed, 0FFH h/w error
F_WRITE LD H,D ; Pointer to FCB ...
LD L,E ; ... into HL
LD BC,14 ; Offset to S2 field (reserved field)
ADD HL,BC ; Compute address
LD A,(HL) ; Obtain file reference num from FCB S2
LD (FWMLIN),A ; Store in parameter list
CALL GETIOADDR ; Get I/O address
CP 0FFH ; See if it was an error
JP Z,FWERR ; If so, abort
LD BC,OFFSET ; Convert to 6502 address
ADD HL,BC ; ...
LD (FWMLIDB),HL ; Store I/O buffer address in parm list
; DEBUG -------------------------------------------
; LD DE,HEXBUF ; Generate hex string to HEXBUF
; CALL NUM2HEX ; ...
; LD DE,HEXBUF ; Write hex value to console
; LD C,B_C_WRTSTR ;
; CALL BDOS
; END DEBUG ---------------------------------------
LD HL,FWMLI ; Pass address of 6502 JSR instruction
CALL PRODOS ; Invoke ProDOS MLI
CP 0 ; See if there was an error
JP NZ,FWERR ; Handle error
LD L,A ; Return code in L also
RET ; Done
FWERR LD A,0FFH ; TODO: All errors are 0FFH for now
LD L,A ; Return code in L aslo
RET ; Done (error)
FWMLI DEFB 20H,00H,0BFH ; JSR $BF00 in 6502 code
DEFB 0CBH ; ProDOS WRITE call
DEFW FWMLIPL+OFFSET ; Pointer to parm list in 6502 addr space
DEFB 60H ; RTS in 6502 code
FWMLIPL DEFB 4 ; ProDOS PL: Four parameters
FWMLIN DEFB 0 ; ProDOS PL: File reference number
FWMLIDB DEFW 0000H ; ProDOS PL: Data buffer
FWMLIRC DEFW 128 ; ProDOS PL: Request count (bytes to read)
FWMLITC DEFW 0000H ; ProDOS PL: Number of bytes transferred
; Create (and open) file
; DE is the address of the FCB describing the file to create
; Returns error codes in A and L:
@ -606,9 +745,7 @@ F_MAKE CALL MAKEPATH ; Populate PATHLEN and PATH
CALL PRODOS ; Invoke ProDOS MLI
CP 0 ; See if there was an error
JP NZ,FMERR ; Handle error
;;;; CALL F_OPEN ; Open the file using same FCB (DE ptr)
LD A,0 ;;; TEMP DEBUG - SHOULD CALL F_OPEN ABOVE ;;;
LD L,A ; Return code in L also
CALL F_OPEN ; Open the file using same FCB (DE ptr)
RET
FMERR LD A,0FFH ; 0FFH for error
LD L,A ; Return code in L also
@ -743,6 +880,36 @@ MPS3 ; EXTENSION
LD (PATHLEN),A ; ...
RET
; Find IOBUF address for a file reference number
; Scan through FRN1, FRN2, FRN3, FRN4 to find the file reference number in A
; If found, return A=0, HL=I/O buffer address
; If not found, return A=0FFH
GETIOADDR LD A,B ; Stash A
LD A,(FRN1) ; Does it match FRN1?
CP B ; ...
JP Z,GIOAS1 ; ...
LD A,(FRN2) ; Does it match FRN2?
CP B ; ...
JP Z,GIOAS2 ; ...
LD A,(FRN3) ; Does it match FRN3?
CP B ; ...
JP Z,GIOAS3 ; ...
LD A,(FRN3) ; Does it match FRN4?
CP B ; ...
JP Z,GIOAS3 ; ...
LD A,0FFH ; No match, return A=0FFH
RET ; ...
GIOAS1 LD HL,IOBUF1 ; Address of I/O buf 1 -> HL
JP GIOAS5 ; ...
GIOAS2 LD HL,IOBUF2 ; Address of I/O buf 2 -> HL
JP GIOAS5 ; ...
GIOAS3 LD HL,IOBUF3 ; Address of I/O buf 3 -> HL
JP GIOAS5 ; ...
GIOAS4 LD HL,IOBUF4 ; Address of I/O buf 4 -> HL
JP GIOAS5 ; ...
GIOAS5 LD A,0 ; Success!
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
NUM2HEX LD A,H
@ -793,10 +960,13 @@ HEXBUF DEFB 0,0,0,0,'$'
; IOBUF4 $B700-$BAFF
ORG 7000H ; Set to 7000H by experiment ...
IOBUF1 DEFS 1024 ; ... we need BASIC.SYSTEM for now since we use EXEC!
IOBUF2 DEFS 1024
IOBUF3 DEFS 1024
IOBUF4 DEFS 1024
IOBUF1 DEFM 'Mary had a little lamb'
ORG 7400H
IOBUF2 DEFM 'His fleece was white as snow'
ORG 7800H
IOBUF3 DEFM 'And everywhere that Mary went'
ORG 7C00H
IOBUF4 DEFM 'That sheep was sure to go'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Binary file not shown.

Binary file not shown.