mirror of
https://github.com/bobbimanners/Zapple-II.git
synced 2024-09-28 17:55:16 +00:00
F_SFIRST and F_SNEXT seem to be working now :)
This commit is contained in:
parent
dc47f0c427
commit
d5a7781195
@ -6,6 +6,28 @@
|
||||
; Tabstops every 4 chars.
|
||||
; Bobbi 2019
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; References:
|
||||
; 1) BDOS System Calls
|
||||
; https://www.seasip.info/Cpm/bdos.html
|
||||
; 2) Programmer's CP/M Handbook - Johnson-Laird
|
||||
; 3) ProDOS 8 Technical Reference Manual
|
||||
; http://www.easy68k.com/paulrsm/6502/PDOS8TRM.HTM
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;
|
||||
; TODO: Finish F_SFIRST, F_SNEXT directory calls
|
||||
; TODO: Implement missing system calls:
|
||||
; - Random read/write (F_READRAND,F_WRITERAND,F_RANDREC)
|
||||
; - RS232 (A_READ, A_WRITE)
|
||||
; - Printer (LWRITE)
|
||||
; - Other (DRV_ALLOCVEC, F_ATTRIB, DRV_DPB, F_WRITEZF)
|
||||
; TODO: IOBYTE doesn't do anything
|
||||
; TODO: User number doesn't do anything
|
||||
; TODO: Software R/O disk setting is not respected
|
||||
; TODO: C_READSTR - Line editing functions
|
||||
; TODO: C_WRITE - ^S,^Q, tabs etc.
|
||||
; Other Random TODO comments in the code
|
||||
;
|
||||
|
||||
BDOSADDR EQU 06000H ;
|
||||
STCKTOP EQU 06FFFH ; Top of Z80 stack (below IOBUFs)
|
||||
@ -127,7 +149,7 @@ S1 LD C,B_C_STAT ;
|
||||
LD C,B_C_WRITE ;
|
||||
CALL BDOS ;
|
||||
|
||||
; Create an FCB
|
||||
; Create FCB1 'A:TEST.TXT'
|
||||
LD A,1 ; A: drive
|
||||
LD (FCB1DRV),A ;
|
||||
LD A,'T' ; Filename
|
||||
@ -153,8 +175,24 @@ S1 LD C,B_C_STAT ;
|
||||
LD A,'T' ; Extension
|
||||
LD (FCB1NAM+10),A ;
|
||||
|
||||
; Create FCB2 'A:????????.???'
|
||||
LD A,1 ; A: drive
|
||||
LD (FCB2DRV),A ;
|
||||
LD A,'?' ; Filename
|
||||
LD (FCB2NAM),A ;
|
||||
LD (FCB2NAM+1),A ;
|
||||
LD (FCB2NAM+2),A ;
|
||||
LD (FCB2NAM+3),A ;
|
||||
LD (FCB2NAM+4),A ;
|
||||
LD (FCB2NAM+5),A ;
|
||||
LD (FCB2NAM+6),A ;
|
||||
LD (FCB2NAM+7),A ;
|
||||
LD (FCB2NAM+8),A ;
|
||||
LD (FCB2NAM+9),A ;
|
||||
LD (FCB2NAM+10),A ;
|
||||
|
||||
; Create and open a file using ProDOS MLI
|
||||
; Creates 'A/TEST.TMP'
|
||||
; Creates 'A/TEST.TXT'
|
||||
; Directory 'A' needs to exist already
|
||||
|
||||
LD DE,CMSG ; Address of string
|
||||
@ -246,13 +284,13 @@ PRFNF LD C,B_C_WRTSTR ;
|
||||
|
||||
;CALL CHECKOK
|
||||
|
||||
; Search for the file in the directory (not existing)
|
||||
; Search for all files in the directory using wildcards
|
||||
|
||||
LD DE,SFMSG2 ; Address of string
|
||||
LD C,B_C_WRTSTR ;
|
||||
CALL BDOS ;
|
||||
|
||||
LD DE,FCB2 ; Default FCB address 2 (uninitialized)
|
||||
LD DE,FCB2 ; Default FCB address 2
|
||||
LD C,B_F_SFIRST ;
|
||||
CALL BDOS ;
|
||||
|
||||
@ -260,10 +298,36 @@ PRFNF LD C,B_C_WRTSTR ;
|
||||
JP Z,FOUND2 ;
|
||||
LD DE,SFMSGNF ;
|
||||
JP PRFNF2 ;
|
||||
FOUND2 LD DE,SFMSGF ;
|
||||
FOUND2 LD A,13 ; HACK to terminate string
|
||||
LD (FILEBUF+12),A ;
|
||||
LD A,'$' ;
|
||||
LD (FILEBUF+13),A ;
|
||||
LD DE,FILEBUF+1 ;
|
||||
LD C,B_C_WRTSTR ;
|
||||
CALL BDOS ;
|
||||
JP DIRLOOP ; Jump forwards to DIR loop
|
||||
PRFNF2 LD C,B_C_WRTSTR ;
|
||||
CALL BDOS ;
|
||||
|
||||
DIRLOOP LD DE,FCB2 ; Default FCB address 2
|
||||
LD C,B_F_SNEXT ;
|
||||
CALL BDOS ;
|
||||
|
||||
CP 0 ;
|
||||
JP Z,FOUND3 ;
|
||||
LD DE,SFMSGNF ;
|
||||
JP PRFNF3 ;
|
||||
FOUND3 LD A,13 ; HACK to terminate string
|
||||
LD (FILEBUF+12),A ;
|
||||
LD A,'$' ;
|
||||
LD (FILEBUF+13),A ;
|
||||
LD DE,FILEBUF+1 ;
|
||||
LD C,B_C_WRTSTR ;
|
||||
CALL BDOS ;
|
||||
JP DIRLOOP ; Loop for all files in dir
|
||||
PRFNF3 LD C,B_C_WRTSTR ;
|
||||
CALL BDOS ;
|
||||
|
||||
;CALL CHECKOK
|
||||
|
||||
; Overwrite DMA buffer just to be sure it is read
|
||||
@ -368,19 +432,19 @@ WELCOME DEFB 13
|
||||
DEFB 13, '$'
|
||||
|
||||
CMSG DEFB 13
|
||||
DEFM 'Creating & opening A/TEST.TMP'
|
||||
DEFM 'Creating & opening A/TEST.TXT'
|
||||
DEFB 13, '$'
|
||||
|
||||
WMSG DEFB 13
|
||||
DEFM 'Writing record to A/TEST.TMP'
|
||||
DEFM 'Writing record to A/TEST.TXT'
|
||||
DEFB 13, '$'
|
||||
|
||||
CLMSG DEFB 13
|
||||
DEFM 'Closing A/TEST.TMP'
|
||||
DEFM 'Closing A/TEST.TXT'
|
||||
DEFB 13, '$'
|
||||
|
||||
SFMSG DEFB 13
|
||||
DEFM 'Searching directory for TEST.TMP'
|
||||
DEFM 'Searching directory for TEST.TXT'
|
||||
DEFB 13, '$'
|
||||
|
||||
SFMSGF DEFB 'Found'
|
||||
@ -390,19 +454,19 @@ SFMSGNF DEFB 'NOT found'
|
||||
DEFB 13, '$'
|
||||
|
||||
SFMSG2 DEFB 13
|
||||
DEFM 'Searching directory for garbage'
|
||||
DEFM 'Searching directory for ????????.???'
|
||||
DEFB 13, '$'
|
||||
|
||||
OMSG DEFB 13
|
||||
DEFM 'Opening A/TEST.TMP'
|
||||
DEFM 'Opening A/TEST.TXT'
|
||||
DEFB 13, '$'
|
||||
|
||||
RMSG DEFB 13
|
||||
DEFM 'Reading record from A/TEST.TMP'
|
||||
DEFM 'Reading record from A/TEST.TXT'
|
||||
DEFB 13, '$'
|
||||
|
||||
DMSG DEFB 13
|
||||
DEFM 'Deleting A/TEST.TMP'
|
||||
DEFM 'Deleting A/TEST.TXT'
|
||||
DEFB 13, '$'
|
||||
|
||||
SUCCMSG DEFM 'Success!'
|
||||
@ -823,25 +887,26 @@ ENTPERBLK EQU 0DH ; Number of file entries per block
|
||||
; Search for first match of filename in directory
|
||||
; DE is the address of the FCB describing the file to look for
|
||||
; Returns error codes in A and L: 0-3 for success, 0FFH for not found
|
||||
; TODO: WRITE THIS
|
||||
; The matching FCB is always in slot 0, so success return code always 0
|
||||
F_SFIRST PUSH DE ; Store pointer to search FCB
|
||||
LD A,(DE) ; Obtain drive number
|
||||
LD (DFCBDRV),A ; Copy to directory FCB
|
||||
LD DE,DFCB ; Use this FCB to open the directory
|
||||
CALL F_CLOSE ; Close the directory, if open
|
||||
CALL CHECKOK
|
||||
LD DE,DFCB ; Use this FCB to open the directory
|
||||
CALL F_OPEN ; Open the directory
|
||||
CALL CHECKOK
|
||||
|
||||
;; TODO: FRN is in DFCBS2
|
||||
|
||||
LD DE,DFCB ; Use this FCB to open the directory
|
||||
FSFL1 LD DE,DFCB ; Use this FCB to read the directory
|
||||
CALL RDDIRBLK ; Read first 512 byte block
|
||||
CP 0 ; See if it was an error
|
||||
JP NZ,FSFS2 ; If error, assume EOF & just return
|
||||
|
||||
LD HL,DIRBUF ; Skip over directory header
|
||||
LD BC,DIRHDSZ ; ...
|
||||
ADD HL,BC ; ...
|
||||
LD (CDBPTR),HL ; Start out at first file entry
|
||||
LD A,0 ; Set file count to zero
|
||||
LD (CDBCOUNT),A ; ...
|
||||
|
||||
POP DE ; Get ptr to search FCB back
|
||||
PUSH HL ; Preserve HL
|
||||
@ -849,12 +914,45 @@ F_SFIRST PUSH DE ; Store pointer to search FCB
|
||||
POP HL ; Restore HL
|
||||
CP 0 ; See if it was a match
|
||||
JP Z,FSFS1 ; If so, return
|
||||
LD A,0FFH ; No match
|
||||
RET ;
|
||||
FSFS1 LD A,0 ; Match
|
||||
RET
|
||||
; TODO Need to read subsequent blocks and work out how to stop!
|
||||
JP FSFL1 ; Loop
|
||||
|
||||
FSFS1 LD A,0 ; Match
|
||||
RET ;
|
||||
FSFS2 LD A,0FFH ; No match
|
||||
RET
|
||||
|
||||
; Search for next match of filename in directory
|
||||
; DE is the address of the FCB describing the file to look for
|
||||
; Returns error codes in A and L: 0-3 for success, 0FFH for not found
|
||||
; The matching FCB is always in slot 0, so success return code always 0
|
||||
F_SNEXT PUSH DE ; Store pointer to search FCB
|
||||
LD HL,(CDBPTR) ; Pointer into current block
|
||||
LD A,(CDBCOUNT) ; File count for current block
|
||||
FSNL1 PUSH HL ; Preserve HL
|
||||
CALL CHKDIRBLK ; Search directory block
|
||||
POP HL ; Restore HL
|
||||
POP DE ; Restore DE
|
||||
CP 0 ; See if it was a match
|
||||
JP Z,FSNS1 ; If so, return
|
||||
|
||||
LD DE,DFCB ; Use this FCB to read the directory
|
||||
CALL RDDIRBLK ; Read next 512 byte block
|
||||
CP 0 ; See if it was an error
|
||||
JP NZ,FSNS2 ; If error, assume EOF & just return
|
||||
|
||||
LD HL,DIRBUF ; Skip over directory header
|
||||
LD BC,DIRHDSZ ; ...
|
||||
ADD HL,BC ; ...
|
||||
LD (CDBPTR),HL ; Start out at first file entry
|
||||
LD A,0 ; Set file count to zero
|
||||
LD (CDBCOUNT),A ; ...
|
||||
|
||||
JP FSNL1 ; Loop
|
||||
|
||||
FSNS1 LD A,0 ; Match
|
||||
RET ;
|
||||
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)
|
||||
@ -866,15 +964,6 @@ DFCBS1 DEFB 00H ; FCB S1 field
|
||||
DFCBS2 DEFB 00H ; FCB S2 field
|
||||
DFCBRC DEFB 00H ; FCB RC field
|
||||
|
||||
; Search for next match of filename in directory
|
||||
; DE is the address of the FCB describing the file to look for
|
||||
; Returns error codes in A and L: 0-3 for success, 0FFH for not found
|
||||
; TODO: WRITE THIS
|
||||
F_SNEXT
|
||||
; PUSH DE ; Store pointer to search FCB
|
||||
; ...
|
||||
RET
|
||||
|
||||
; Delete file
|
||||
; DE is the address of the FCB describing the file to delete
|
||||
; Returns error codes in A and L:
|
||||
@ -1283,40 +1372,45 @@ P2FS2 LD DE,FILEBUF+8 ; Destination is start of extension
|
||||
; Read 512 byte block of directory
|
||||
; Used by F_SFIRST and F_SNEXT
|
||||
; Trashes HL + registers trashed by F_READ (best to assume all of them!)
|
||||
; Returns A=0 for success, A=0FFH on error
|
||||
RDDIRBLK LD HL,(DMAADDR) ; Save existing DMA address
|
||||
PUSH HL ; ...
|
||||
|
||||
|
||||
; Read first 512 byte block of directory
|
||||
LD DE,DFCB ; Use this FCB to open the directory
|
||||
LD HL,DIRBUF1 ; Set DMAADDR to point to DIRBUF1
|
||||
LD (DMAADDR),HL ; ...
|
||||
CALL F_READ ; Read first block of directory
|
||||
|
||||
CALL CHECKOK
|
||||
CALL F_READ ; Read first record of directory
|
||||
CP 0 ; See if there was an error
|
||||
JP NZ,RDBS1 ; If so, quit with error code
|
||||
|
||||
LD DE,DFCB ; Use this FCB to open the directory
|
||||
LD HL,DIRBUF2 ; Set DMAADDR to point to DIRBUF2
|
||||
LD (DMAADDR),HL ; ...
|
||||
CALL F_READ ; Read first block of directory
|
||||
|
||||
CALL CHECKOK
|
||||
CALL F_READ ; Read second record of directory
|
||||
CP 0 ; See if there was an error
|
||||
JP NZ,RDBS1 ; If so, quit with error code
|
||||
|
||||
LD DE,DFCB ; Use this FCB to open the directory
|
||||
LD HL,DIRBUF3 ; Set DMAADDR to point to DIRBUF3
|
||||
LD (DMAADDR),HL ; ...
|
||||
CALL F_READ ; Read first block of directory
|
||||
|
||||
CALL CHECKOK
|
||||
CALL F_READ ; Read third record of directory
|
||||
CP 0 ; See if there was an error
|
||||
JP NZ,RDBS1 ; If so, quit with error code
|
||||
|
||||
LD DE,DFCB ; Use this FCB to open the directory
|
||||
LD HL,DIRBUF4 ; Set DMAADDR to point to DIRBUF4
|
||||
LD (DMAADDR),HL ; ...
|
||||
CALL F_READ ; Read first block of directory
|
||||
CALL F_READ ; Read fourth record of directory
|
||||
CP 0 ; See if there was an error
|
||||
JP NZ,RDBS1 ; If so, quit with error code
|
||||
|
||||
CALL CHECKOK
|
||||
LD A,0 ; Return code for success
|
||||
JP RDBS2 ; Successful return
|
||||
|
||||
POP HL ; Reset DMA address as we found it
|
||||
RDBS1 LD A,0FFH ; Error return code
|
||||
|
||||
RDBS2 POP HL ; Reset DMA address as we found it
|
||||
LD (DMAADDR),HL ; ...
|
||||
RET
|
||||
|
||||
@ -1378,27 +1472,34 @@ CDES2 LD A,0 ; Match
|
||||
; Search a 512 byte block of a ProDOS directory for a matching file entry
|
||||
; Used by F_SFIRST and F_SNEXT
|
||||
; DE is the address of the FCB describing the file to look for
|
||||
; HL points to the first file entry in the ProDOS directory
|
||||
; CDBPTR points to the next ProDOS file entry to parse
|
||||
; CDBCOUNT is set to the number of file entries already parsed in this block
|
||||
; Returns A=0 if entry matches, A=FFH if no match
|
||||
CHKDIRBLK LD A,0 ; File entry counter
|
||||
CDBL1 PUSH AF ; Preserve A
|
||||
PUSH HL ; Preserve HL
|
||||
CALL CHKDIRENT ; Match the file entry at HL
|
||||
POP HL ; Restore HL
|
||||
CP 0 ; Was it a match?
|
||||
JP Z,CDBS1 ; If so, we are done
|
||||
POP AF ; Restore A
|
||||
CHKDIRBLK LD A,(CDBCOUNT) ; File entry counter
|
||||
LD HL,(CDBPTR) ; Pointer to next file entry
|
||||
CDBL1 CALL CHKDIRENT ; Match the file entry at HL
|
||||
EX AF,AF' ; Stash return code for now
|
||||
LD BC,FILEENTSZ ; Advance to next file entry
|
||||
ADD HL,BC ; ...
|
||||
LD (CDBPTR),HL ; Store the pointer
|
||||
LD A,(CDBCOUNT) ; File entry counter
|
||||
INC A ; Increment count of file entries
|
||||
LD (CDBCOUNT),A ; Store the counter
|
||||
EX AF,AF' ; Get return code back in A
|
||||
CP 0 ; Was it a match?
|
||||
JP Z,CDBS1 ; If so, we are done
|
||||
LD A,(CDBCOUNT) ; Get the counter back
|
||||
CP ENTPERBLK ; Done all of them in this block?
|
||||
JP NZ,CDBL1 ; If not, loop
|
||||
LD A,0FFH ; No match
|
||||
RET ;
|
||||
CDBS1 POP AF ; Restore stack
|
||||
LD A,0 ; Match
|
||||
CDBS1 LD A,0 ; Match
|
||||
RET
|
||||
|
||||
; The following variables are used to preserve state between calls
|
||||
CDBPTR DEFW 0000H ; Stores pointer to next file entry
|
||||
CDBCOUNT DEFB 0 ; Stores file entry counter
|
||||
|
||||
; 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 FRN slot# 1,2,3,4 in A, I/O buffer address in HL
|
||||
|
Binary file not shown.
BIN
zapple2.po
BIN
zapple2.po
Binary file not shown.
Loading…
Reference in New Issue
Block a user