]> git.defcon.no Git - z80cpm/commitdiff
An experiment in reading files on CP/M master
authorJon Langseth <jon.langseth@ntnu.no>
Wed, 8 Feb 2017 19:27:48 +0000 (20:27 +0100)
committerJon Langseth <jon.langseth@ntnu.no>
Wed, 8 Feb 2017 19:27:48 +0000 (20:27 +0100)
rf1.asm [new file with mode: 0644]

diff --git a/rf1.asm b/rf1.asm
new file mode 100644 (file)
index 0000000..f30699d
--- /dev/null
+++ b/rf1.asm
@@ -0,0 +1,129 @@
+; rf1.asm - Read File experiment #1
+; ASM dialect is for crasm/z80, producing Intel HEX.
+;
+; Attempting to understand file read operations on CP/M2
+; Reference material:
+; http://www.cpm.z80.de/manuals/archive/cpm22htm/ch5.htm
+; The default FCB can be used, it's location is at 05CH
+; The default DMA buffer can be used, it's located at 080H
+; When CCP jumps to 0100H, it's already taken the two
+; first parameters to the command, and placed them in
+; the default FCB area. More on this later in the code
+; CCP has also placed the parameter string in the default
+; DMA buffer area (080H). Not used in this experiment.
+
+; crasm macros.. Z80 CPU type, iHEX output, readable listing pages, listing-toggles..
+CPU Z80
+OUTPUT HEX
+PAGE 24,120
+LIST ON
+CLIST ON
+ILIST ON
+MLIST ON
+
+; BDOS call constants..
+conout EQU 2           ; Console output, put 1 char from E to Console
+strout EQU 9           ; String output, place string at (DE) terminated by $ to Console
+openf  EQU 15          ; Open file, using the FCB at address (DE)
+reads  EQU 20          ; Read sequential, get next DMABUF from file at FCB in (DE)
+closef EQU 16          ; Close file, using hte FCB at (DE)
+bdos   EQU 5           ; Call jump-address for all BDOS calls.
+
+; Standard location constants..
+sfcb   EQU 0x5c        ; The Standard/default FCB
+fcbcr  EQU sfcb+32     ; The CR field of the FCB
+sdma   EQU 0x80        ; The Standard/default DMA Buffer
+
+; Other fun constants...
+eof    EQU 0x1a        ; CP/M EOF character, 0x1Ah/26d
+
+; Origin at TPA Start, 0x100
+* = 0x100
+
+       ; Start by printing out the filename currently in the default FCB.
+       ; CCP will take 'command file.sfx file1.sfx" and fill the default
+       ; FCB appropriately for file.sfx, plus the needed content for a
+       ; second FCB started at 0x6c (default fcb + 10h)
+       ; The Drive index is the first byte, and the filename is 8+3 bytes
+       LD HL, sfcb + 1 ; Load HL with address of Standard FCB + 1
+       LD D, 8+3       ; Prepare a counter for 8+3 characters for a full filename
+START  LD E, (HL)      ; Load content of address in HL into E
+       LD C, conout    ; Prepare a Console Character Out BDOS call
+       PUSH HL         ; BDOS call clobbers HL, push to stack
+       CALL bdos       ; Go to BDOS for conout call
+       POP HL          ; Restore HL after BDOS call
+       INC HL          ; Next byte
+       DEC D           ; .. until all needed characters..
+       JR NZ, START
+
+       ; --- START OF FILE OPEN
+       ; To open file for sequential access, the 'cr' field of the FCB needs
+       ; to be zeroed
+       LD HL, fcbcr    ; Set the HL register pair to the CR field address
+       LD (HL), 0      ; Set to zero
+
+       LD DE, sfcb     ; Prepare DE with address of FCB
+       LD C, openf     ; Set up for Open File BDOS call
+       CALL bdos       ; GO!
+
+       CP 255          ; Compare A register to check for error
+       JR Z, ERROPF    ; If Zero set, A == 255, and we have an error
+       ; --- END OF FILE OPEN
+
+       LD DE, okmsg    ; Compare did not set Zero flag, so we can
+       LD C, strout    ; use String Output to say that the file is opened
+       CALL bdos
+
+       ; --- ACTUAL DATA REA
+RREC   LD DE, sfcb     ; Load DE with address of FCB
+       LD C, reads     ; and perform a sequential file read
+       CALL bdos       ; BDOS will look at the FCB and retrieve the appropriate block
+
+       CP 0            ; Check for errors on read. If we see anything other than
+       JR NZ, ERRRDD   ; a zero, we have something wonky on the read.
+       ; --- DMA buffer now contains 128 bytes from file
+
+       ; --- Fluff of code to read through file
+       LD D, 128       ; Prepare for counting through 128 bytes record...
+       LD HL, sdma     ; Using the HL as a pointer to positions on DMA buffer
+PRTBYTE        LD E, (HL)      ; Load content of address in HL into E
+
+       ; This bit works for text, will be wonky if the file is binary
+       ; But, it seems that if a record is not full, it's supposed to get
+       ; filled with EOF characters until end...
+       LD A, eof       ; Check for EOF character
+       CP E            ; If cound, we're at the end of file
+       JR Z, DONE      ; .. so jump to done
+
+       LD C, conout    ; Prepare a Console Character Out BDOS call
+       PUSH HL         ; BDOS call clobbers HL, push to stack
+       CALL bdos       ; Go to BDOS for conout call
+       POP HL          ; Restore HL after BDOS call
+       INC HL          ; Next byte
+       DEC D           ; .. until all needed characters..
+       JR NZ, PRTBYTE
+
+       ; If we've gotten here, we have completed one 128 byte set, and
+       ; haven't seen any EOF characters yet. So, try to get a new one.
+       JP RREC         ; Jump to read next record from file.
+
+
+DONE   LD DE, donemsg  ; Do a quick status at the end of completion...
+       LD C, strout
+       CALL bdos
+       JP  0           ; Do a jump to BOOT, causing a boot to CCP
+
+ERROPF LD DE, erropn
+       JP ERROR
+ERRRDD LD DE, errrd
+       JP ERROR
+
+ERROR  LD C, strout
+       CALL bdos
+       JP  0           ; Do a jump to BOOT, causing a boot to CCP
+
+erropn ASC "\r\n---> ERROR opening file\r\n$"
+errrd  ASC "\r\n---> ERROR reading file\r\n$"
+okmsg  ASC "\r\n---> Opened file\r\n$"
+donemsg        ASC "\r\n---> Completed reading file.\r\n$"
+