From 565973c5203e613428597001a4e971d363dea167 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 3 Dec 2024 22:51:56 +0100 Subject: [PATCH] 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 --- compiler/res/prog8lib/cx16/diskio.p8 | 21 ++++++++++++++++----- compiler/res/prog8lib/shared_cbm_diskio.p8 | 15 ++++++++++++--- compiler/res/prog8lib/virtual/diskio.p8 | 4 ++-- docs/source/libraries.rst | 5 ----- docs/source/todo.rst | 2 -- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/compiler/res/prog8lib/cx16/diskio.p8 b/compiler/res/prog8lib/cx16/diskio.p8 index 94271367c..cef3f6d09 100644 --- a/compiler/res/prog8lib/cx16/diskio.p8 +++ b/compiler/res/prog8lib/cx16/diskio.p8 @@ -331,6 +331,7 @@ close_end: ; optimize for reading just a single byte @(bufferpointer) = cbm.CHRIN() cx16.r0L = cbm.READST() + cbm.CLRCHN() ; reset default i/o channels if cx16.r0L!=0 { f_close() if cx16.r0L & $40 == 0 @@ -358,6 +359,7 @@ close_end: break } } + cbm.CLRCHN() ; reset default i/o channels return list_blocks ; number of bytes read 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() - if cx16.r0L!=0 { + if_nz { f_close() + cbm.CLRCHN() ; reset default i/o channels if cx16.r0L & $40 !=0 ; eof? return list_blocks ; number of bytes read return 0 ; error. @@ -386,6 +389,7 @@ m_in_buffer sta $ffff list_blocks++ num_bytes-- } + cbm.CLRCHN() ; reset default i/o channels return list_blocks ; number of bytes read } @@ -404,12 +408,13 @@ m_in_buffer sta $ffff total_read += cx16.r0 bufferpointer += cx16.r0 } + cbm.CLRCHN() ; reset default i/o channels return total_read } 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. - ; 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 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. @@ -430,6 +435,9 @@ _line_end dey ; get rid of the trailing end-of-line char lda #0 sta (P8ZP_SCRATCH_W1),y _end jsr cbm.READST + pha + jsr cbm.CLRCHN + pla rts }} } @@ -478,9 +486,9 @@ _end jsr cbm.READST if msb(bufferpointer) == $c0 bufferpointer = mkword($a0, lsb(bufferpointer)) ; wrap over bank boundary if cbm.READST()!=0 - return false + goto return_status } until num_bytes==0 - return cbm.READST()==0 + goto return_status no_mciout: ; the device doesn't support MCIOUT, use a normal per-byte write loop @@ -488,7 +496,10 @@ no_mciout: cbm.CHROUT(@(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 } diff --git a/compiler/res/prog8lib/shared_cbm_diskio.p8 b/compiler/res/prog8lib/shared_cbm_diskio.p8 index 6fab0c4db..bd78dd37e 100644 --- a/compiler/res/prog8lib/shared_cbm_diskio.p8 +++ b/compiler/res/prog8lib/shared_cbm_diskio.p8 @@ -309,6 +309,7 @@ close_end: ; slightly optimized path for reading just a single byte @(bufferpointer) = cbm.CHRIN() cx16.r0L = cbm.READST() + cbm.CLRCHN() ; reset default i/o channels if cx16.r0L!=0 { f_close() if cx16.r0L & $40 == 0 @@ -334,8 +335,9 @@ m_in_buffer sta $ffff + }} cx16.r0L = cbm.READST() - if cx16.r0L!=0 { + if_nz { f_close() + cbm.CLRCHN() ; reset default i/o channels if cx16.r0L & $40 !=0 ; eof? return list_blocks ; number of bytes read return 0 ; error. @@ -343,6 +345,7 @@ m_in_buffer sta $ffff list_blocks++ num_bytes-- } + cbm.CLRCHN() ; reset default i/o channels return list_blocks ; number of bytes read } @@ -359,12 +362,13 @@ m_in_buffer sta $ffff total_read += cx16.r0 bufferpointer += cx16.r0 } + cbm.CLRCHN() ; reset default i/o channels return total_read } 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. - ; 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 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. @@ -386,6 +390,9 @@ _line_end dey ; get rid of the trailing end-of-line char lda #0 sta (P8ZP_SCRATCH_W1),y _end jsr cbm.READST + pha + jsr cbm.CLRCHN + pla rts }} } @@ -438,7 +445,9 @@ _end jsr cbm.READST cbm.CHROUT(@(bufferpointer)) bufferpointer++ } - return cbm.READST()==0 + cx16.r0L = cbm.READST() + cbm.CLRCHN() ; reset default i/o channels + return cx16.r0L==0 } return true } diff --git a/compiler/res/prog8lib/virtual/diskio.p8 b/compiler/res/prog8lib/virtual/diskio.p8 index 4e3db92e1..9e28a734d 100644 --- a/compiler/res/prog8lib/virtual/diskio.p8 +++ b/compiler/res/prog8lib/virtual/diskio.p8 @@ -107,7 +107,7 @@ diskio { sub f_readline(uword bufptr) -> ubyte { ; 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 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 @@ -122,7 +122,7 @@ diskio { sys.clear_carry() return size } else { - if cx16.r0L == '\n' or cx16.r0L=='\r' { + if cx16.r0L in ['\n', '\r', 0] { @(bufptr) = 0 sys.set_carry() return size diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index c70bafefb..873f212f6 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -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. 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:: 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. diff --git a/docs/source/todo.rst b/docs/source/todo.rst index df3a13e26..48e2bf69b 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,8 +1,6 @@ TODO ==== -make a compiler switch to disable footgun warnings -ignorefootguns - update zsmkit to newest version that includes the on_deck routines when stabilized