diskio.f_open_w() now also resets io channels back to defaults, like f_open() already did

This commit is contained in:
Irmen de Jong 2024-12-02 22:05:23 +01:00
parent 8fa14a10e2
commit 28cac291de
5 changed files with 55 additions and 54 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}
}