diskio read & write routines now always reset the io channels back to the defaults before returning

This means you don't have to call CLRCHN yourself anymore inbetween if you want to do screen output or keyboard input while a file is open
This commit is contained in:
Irmen de Jong 2024-12-03 22:51:56 +01:00
parent 25b1043572
commit 565973c520
5 changed files with 30 additions and 17 deletions

View File

@ -331,6 +331,7 @@ close_end:
; optimize for reading just a single byte ; optimize for reading just a single byte
@(bufferpointer) = cbm.CHRIN() @(bufferpointer) = cbm.CHRIN()
cx16.r0L = cbm.READST() cx16.r0L = cbm.READST()
cbm.CLRCHN() ; reset default i/o channels
if cx16.r0L!=0 { if cx16.r0L!=0 {
f_close() f_close()
if cx16.r0L & $40 == 0 if cx16.r0L & $40 == 0
@ -358,6 +359,7 @@ close_end:
break break
} }
} }
cbm.CLRCHN() ; reset default i/o channels
return list_blocks ; number of bytes read return list_blocks ; number of bytes read
byte_read_loop: ; fallback if MACPTR isn't supported on the device byte_read_loop: ; fallback if MACPTR isn't supported on the device
@ -377,8 +379,9 @@ m_in_buffer sta $ffff
+ +
}} }}
cx16.r0L = cbm.READST() cx16.r0L = cbm.READST()
if cx16.r0L!=0 { if_nz {
f_close() f_close()
cbm.CLRCHN() ; reset default i/o channels
if cx16.r0L & $40 !=0 ; eof? if cx16.r0L & $40 !=0 ; eof?
return list_blocks ; number of bytes read return list_blocks ; number of bytes read
return 0 ; error. return 0 ; error.
@ -386,6 +389,7 @@ m_in_buffer sta $ffff
list_blocks++ list_blocks++
num_bytes-- num_bytes--
} }
cbm.CLRCHN() ; reset default i/o channels
return list_blocks ; number of bytes read return list_blocks ; number of bytes read
} }
@ -404,12 +408,13 @@ m_in_buffer sta $ffff
total_read += cx16.r0 total_read += cx16.r0
bufferpointer += cx16.r0 bufferpointer += cx16.r0
} }
cbm.CLRCHN() ; reset default i/o channels
return total_read return total_read
} }
asmsub f_readline(uword bufptr @AY) clobbers(X) -> ubyte @Y, ubyte @A { asmsub f_readline(uword bufptr @AY) clobbers(X) -> ubyte @Y, ubyte @A {
; Routine to read text lines from a text file. Lines must be less than 255 characters. ; Routine to read text lines from a text file. Lines must be less than 255 characters.
; Reads characters from the input file UNTIL a newline or return character (or EOF). ; Reads characters from the input file UNTIL a newline or return character, or 0 byte (likely EOF).
; The line read will be 0-terminated in the buffer (and not contain the end of line character). ; The line read will be 0-terminated in the buffer (and not contain the end of line character).
; The length of the line is returned in Y. Note that an empty line is okay and is length 0! ; The length of the line is returned in Y. Note that an empty line is okay and is length 0!
; The I/O error status byte is returned in A. ; The I/O error status byte is returned in A.
@ -430,6 +435,9 @@ _line_end dey ; get rid of the trailing end-of-line char
lda #0 lda #0
sta (P8ZP_SCRATCH_W1),y sta (P8ZP_SCRATCH_W1),y
_end jsr cbm.READST _end jsr cbm.READST
pha
jsr cbm.CLRCHN
pla
rts rts
}} }}
} }
@ -478,9 +486,9 @@ _end jsr cbm.READST
if msb(bufferpointer) == $c0 if msb(bufferpointer) == $c0
bufferpointer = mkword($a0, lsb(bufferpointer)) ; wrap over bank boundary bufferpointer = mkword($a0, lsb(bufferpointer)) ; wrap over bank boundary
if cbm.READST()!=0 if cbm.READST()!=0
return false goto return_status
} until num_bytes==0 } until num_bytes==0
return cbm.READST()==0 goto return_status
no_mciout: no_mciout:
; the device doesn't support MCIOUT, use a normal per-byte write loop ; the device doesn't support MCIOUT, use a normal per-byte write loop
@ -488,7 +496,10 @@ no_mciout:
cbm.CHROUT(@(bufferpointer)) cbm.CHROUT(@(bufferpointer))
bufferpointer++ bufferpointer++
} }
return cbm.READST()==0 return_status:
cx16.r0L = cbm.READST()
cbm.CLRCHN() ; reset default i/o channels
return cx16.r0L==0
} }
return true return true
} }

View File

@ -309,6 +309,7 @@ close_end:
; slightly optimized path for reading just a single byte ; slightly optimized path for reading just a single byte
@(bufferpointer) = cbm.CHRIN() @(bufferpointer) = cbm.CHRIN()
cx16.r0L = cbm.READST() cx16.r0L = cbm.READST()
cbm.CLRCHN() ; reset default i/o channels
if cx16.r0L!=0 { if cx16.r0L!=0 {
f_close() f_close()
if cx16.r0L & $40 == 0 if cx16.r0L & $40 == 0
@ -334,8 +335,9 @@ m_in_buffer sta $ffff
+ +
}} }}
cx16.r0L = cbm.READST() cx16.r0L = cbm.READST()
if cx16.r0L!=0 { if_nz {
f_close() f_close()
cbm.CLRCHN() ; reset default i/o channels
if cx16.r0L & $40 !=0 ; eof? if cx16.r0L & $40 !=0 ; eof?
return list_blocks ; number of bytes read return list_blocks ; number of bytes read
return 0 ; error. return 0 ; error.
@ -343,6 +345,7 @@ m_in_buffer sta $ffff
list_blocks++ list_blocks++
num_bytes-- num_bytes--
} }
cbm.CLRCHN() ; reset default i/o channels
return list_blocks ; number of bytes read return list_blocks ; number of bytes read
} }
@ -359,12 +362,13 @@ m_in_buffer sta $ffff
total_read += cx16.r0 total_read += cx16.r0
bufferpointer += cx16.r0 bufferpointer += cx16.r0
} }
cbm.CLRCHN() ; reset default i/o channels
return total_read return total_read
} }
asmsub f_readline(uword bufptr @AY) clobbers(X) -> ubyte @Y, ubyte @A { asmsub f_readline(uword bufptr @AY) clobbers(X) -> ubyte @Y, ubyte @A {
; Routine to read text lines from a text file. Lines must be less than 255 characters. ; Routine to read text lines from a text file. Lines must be less than 255 characters.
; Reads characters from the input file UNTIL a newline or return character (or EOF). ; Reads characters from the input file UNTIL a newline or return character, or 0 byte (likely EOF).
; The line read will be 0-terminated in the buffer (and not contain the end of line character). ; The line read will be 0-terminated in the buffer (and not contain the end of line character).
; The length of the line is returned in Y. Note that an empty line is okay and is length 0! ; The length of the line is returned in Y. Note that an empty line is okay and is length 0!
; I/O error status should be checked by the caller itself via READST() routine. ; I/O error status should be checked by the caller itself via READST() routine.
@ -386,6 +390,9 @@ _line_end dey ; get rid of the trailing end-of-line char
lda #0 lda #0
sta (P8ZP_SCRATCH_W1),y sta (P8ZP_SCRATCH_W1),y
_end jsr cbm.READST _end jsr cbm.READST
pha
jsr cbm.CLRCHN
pla
rts rts
}} }}
} }
@ -438,7 +445,9 @@ _end jsr cbm.READST
cbm.CHROUT(@(bufferpointer)) cbm.CHROUT(@(bufferpointer))
bufferpointer++ bufferpointer++
} }
return cbm.READST()==0 cx16.r0L = cbm.READST()
cbm.CLRCHN() ; reset default i/o channels
return cx16.r0L==0
} }
return true return true
} }

View File

@ -107,7 +107,7 @@ diskio {
sub f_readline(uword bufptr) -> ubyte { sub f_readline(uword bufptr) -> ubyte {
; Routine to read text lines from a text file. Lines must be less than 255 characters. ; Routine to read text lines from a text file. Lines must be less than 255 characters.
; Reads characters from the input file UNTIL a newline or return character (or EOF). ; Reads characters from the input file UNTIL a newline or return character, or 0 byte (likely EOF).
; The line read will be 0-terminated in the buffer (and not contain the end of line character). ; The line read will be 0-terminated in the buffer (and not contain the end of line character).
; The length of the line is returned. Note that an empty line is okay and is length 0! ; The length of the line is returned. Note that an empty line is okay and is length 0!
; The success status is returned in the Carry flag instead: C set = success, C clear = failure/endoffile ; The success status is returned in the Carry flag instead: C set = success, C clear = failure/endoffile
@ -122,7 +122,7 @@ diskio {
sys.clear_carry() sys.clear_carry()
return size return size
} else { } else {
if cx16.r0L == '\n' or cx16.r0L=='\r' { if cx16.r0L in ['\n', '\r', 0] {
@(bufptr) = 0 @(bufptr) = 0
sys.set_carry() sys.set_carry()
return size return size

View File

@ -525,11 +525,6 @@ to see what's in there. (Note: slight variations for different compiler targets)
You can set the active disk drive number, so it supports multiple drives, just one at a time. You can set the active disk drive number, so it supports multiple drives, just one at a time.
It does not support reading from more than one file or writing to more than one file at a time. It does not support reading from more than one file or writing to more than one file at a time.
.. note::
If you want to print text to the screen, or do keyboard input, while reading or writing an open file is in progress,
you should use ``cbm.CLRCHN()`` before doing so. This resets the default i/o channels to screen and keyboard.
Diskio itself is smart enough to set them back to whatever is needed to continue reading/writing with the ``f_read`` or ``f_write`` routines.
.. attention:: .. attention::
Error handling is peculiar on CBM dos systems (C64, C128, cx16, PET). Read the Error handling is peculiar on CBM dos systems (C64, C128, cx16, PET). Read the
descriptions for the various methods in this library for details and tips. descriptions for the various methods in this library for details and tips.

View File

@ -1,8 +1,6 @@
TODO TODO
==== ====
make a compiler switch to disable footgun warnings -ignorefootguns
update zsmkit to newest version that includes the on_deck routines when stabilized update zsmkit to newest version that includes the on_deck routines when stabilized