diff --git a/compiler/res/prog8lib/cx16/diskio.p8 b/compiler/res/prog8lib/cx16/diskio.p8 index 22d98a567..10ae66e2a 100644 --- a/compiler/res/prog8lib/cx16/diskio.p8 +++ b/compiler/res/prog8lib/cx16/diskio.p8 @@ -454,6 +454,8 @@ _end jsr cbm.READST ; (for example, if it already exists). This is different than f_open()! ; To be 100% sure if this call was successful, you have to use status() ; and check the drive's status message! + ; NOTE: the default output isn't yet set to this file, you must use reset_write_channel() to do this, + ; if you're going to write to it yourself instead of using f_write()! return internal_f_open_w(filename, false) } @@ -462,28 +464,6 @@ _end jsr cbm.READST return internal_f_open_w(filename, true) } - sub internal_f_open_w(str filename, bool open_for_seeks) -> bool { - f_close_w() - list_filename = filename - str modifier = ",s,?" - modifier[3] = 'w' - if open_for_seeks - modifier[3] = 'm' - cx16.r0L = strings.append(list_filename, modifier) ; secondary 13 requires a mode suffix to signal we're writing/modifying - cbm.SETNAM(cx16.r0L, list_filename) - cbm.SETLFS(WRITE_IO_CHANNEL, drivenumber, WRITE_IO_CHANNEL) - void cbm.OPEN() ; open 13,8,13,"filename" - if_cc { - if cbm.READST()==0 { - write_iteration_in_progress = true - return true - } - } - cbm.CLOSE(WRITE_IO_CHANNEL) - f_close_w() - return false - } - sub f_write(uword bufferpointer, uword num_bytes) -> bool { ; -- write the given number of bytes to the currently open file ; you can call this multiple times to append more data @@ -523,6 +503,29 @@ no_mciout: } } + sub internal_f_open_w(str filename, bool open_for_seeks) -> bool { + f_close_w() + list_filename = filename + str modifier = ",s,?" + modifier[3] = 'w' + if open_for_seeks + modifier[3] = 'm' + cx16.r0L = strings.append(list_filename, modifier) ; secondary 13 requires a mode suffix to signal we're writing/modifying + cbm.SETNAM(cx16.r0L, list_filename) + cbm.SETLFS(WRITE_IO_CHANNEL, drivenumber, WRITE_IO_CHANNEL) + void cbm.OPEN() ; open 13,8,13,"filename" + if_cc { + if cbm.READST()==0 { + write_iteration_in_progress = true + cbm.CLRCHN() ; reset default i/o channels + return true + } + } + cbm.CLOSE(WRITE_IO_CHANNEL) + f_close_w() + return false + } + ; ---- other functions ---- @@ -892,6 +895,7 @@ io_error: sub exists(str filename) -> bool { ; -- returns true if the given file exists on the disk, otherwise false + ; DON'T use this if you already have a file open with f_open! if f_open(filename) { f_close() return true diff --git a/compiler/res/prog8lib/shared_cbm_diskio.p8 b/compiler/res/prog8lib/shared_cbm_diskio.p8 index 35f99461d..02249f6d1 100644 --- a/compiler/res/prog8lib/shared_cbm_diskio.p8 +++ b/compiler/res/prog8lib/shared_cbm_diskio.p8 @@ -408,6 +408,8 @@ _end jsr cbm.READST ; (for example, if it already exists). This is different than f_open()! ; To be 100% sure if this call was successful, you have to use status() ; and check the drive's status message! + ; NOTE: the default output isn't yet set to this file, you must use reset_write_channel() to do this, + ; if you're going to write to it yourself instead of using f_write()! f_close_w() cbm.SETNAM(strings.length(filenameptr), filenameptr) @@ -416,6 +418,7 @@ _end jsr cbm.READST if_cc { if cbm.READST()==0 { write_iteration_in_progress = true + cbm.CLRCHN() ; reset default i/o channels return true } } @@ -614,6 +617,7 @@ io_error: sub exists(str filename) -> bool { ; -- returns true if the given file exists on the disk, otherwise false + ; DON'T use this if you already have a file open with f_open! if f_open(filename) { f_close() return true diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index 3e93fa9bf..c70bafefb 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -522,8 +522,13 @@ to see what's in there. (Note: slight variations for different compiler targets) It is possible that there are still small differences between HostFS and actual CBM DOS in the X16 emulator. .. note:: - You can set the active disk drive number so it supports multiple drives, - but it does not support multiple open files at the same 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. + +.. 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 diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 7d5e11042..d709fbbcb 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,8 +1,6 @@ TODO ==== -Fix diskio (cx16, possibly other cbm targets too?) when opening write file , read file stops working - add a -plain option to turn off text output coloring and unicode symbols in error messages (footguns) make a compiler switch to disable footgun warnings -ignorefootguns diff --git a/examples/test.p8 b/examples/test.p8 index f01738d0f..bc0e67f4f 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -5,36 +5,26 @@ main { sub start() { - txt.print("----with read 1:\n") - testread1() - txt.print("----with readline:\n") - testreadline() - } - sub testread1() { - if not diskio.f_open("lines.txt") - return - defer diskio.f_close() + if diskio.f_open("lines.txt") { + defer diskio.f_close() - str buffer = " " - while 1==diskio.f_read(&buffer, 1) { - txt.chrout(buffer[0]) + if diskio.f_open_w("@:copy.txt") { + defer diskio.f_close_w() + + str buffer = " "*80 + ubyte length, status + do { + length, status = diskio.f_readline(&buffer) + cbm.CLRCHN() + txt.print_uw(length) + txt.nl() + if length!=0 { + if not diskio.f_write(buffer, length) + return + } + } until status!=0 + } } } - - sub testreadline() { - if not diskio.f_open("lines.txt") - return - defer diskio.f_close() - - str buffer = " "*80 - ubyte length, status - do { - length, status = diskio.f_readline(&buffer) - if length!=0 { - txt.print(buffer) - txt.nl() - } - } until status!=0 - } }