From aa949165c728e1c641c7ec11e7d482b958d3c67f Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 12 Nov 2023 20:40:17 +0100 Subject: [PATCH] diskio.f_open_w() error handling back to what it was before Otherwise it eats the status message. Added comment that you have to check this manually to be sure if the call succeeded or not! --- compiler/res/prog8lib/cx16/diskio.p8 | 42 +++++---- docs/source/libraries.rst | 4 + examples/cx16/fileseek.p8 | 2 +- examples/test.p8 | 123 ++++++++++++++++++++++++++- syntax-files/Vim/prog8_builtins.vim | 1 - 5 files changed, 152 insertions(+), 20 deletions(-) diff --git a/compiler/res/prog8lib/cx16/diskio.p8 b/compiler/res/prog8lib/cx16/diskio.p8 index 9f5892511..bfc701703 100644 --- a/compiler/res/prog8lib/cx16/diskio.p8 +++ b/compiler/res/prog8lib/cx16/diskio.p8 @@ -280,9 +280,11 @@ close_end: ; ----- iterative file loader functions (uses the read io channel) ----- - sub f_open(uword filenameptr) -> bool { + sub f_open(str filenameptr) -> bool { ; -- open a file for iterative reading with f_read ; note: only a single iteration loop can be active at a time! + ; Returns true if the file is successfully opened and readable. + ; No need to check status(), unlike f_open_w() ! f_close() cbm.SETNAM(string.length(filenameptr), filenameptr) @@ -421,24 +423,34 @@ _end rts ; ----- iterative file writing functions (uses write io channel) ----- - sub f_open_w(uword filenameptr) -> bool { - ; -- open a file for iterative writing with f_write - f_close_w() + sub f_open_w(str filename) -> bool { + ; -- Open a file for iterative writing with f_write + ; WARNING: returns true if the open command was received by the device, + ; but this can still mean the file wasn't successfully opened for writing! + ; (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! + return internal_f_open_w(filename, false) + } - ; secondary 13 requires a mode suffix to signal we're writing/modifying - list_filename = filenameptr - cx16.r0L = string.append(list_filename, ",s,m") + sub f_open_w_seek(str filename) -> bool { + ; -- Open an existing file for iterative writing with f_write, and seeking with f_seek_w. + 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 = string.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 { - ; check the drive status to see if it has actually succeeded - cx16.r0 = status() - reset_write_channel() - if @(cx16.r0)=='0' - return true - } + return not cbm.READST() } f_close_w() return false @@ -821,7 +833,7 @@ io_error: sub f_seek_w(uword pos_hiword, uword pos_loword) { - ; -- seek in the output file opened with f_open_w, to the given 32-bits position + ; -- seek in the output file opened with f_open_w_seek, to the given 32-bits position diskio.f_seek.command[1] = WRITE_IO_CHANNEL ; f_open_w uses this secondary address diskio.f_seek.command[2] = lsb(pos_loword) diskio.f_seek.command[3] = msb(pos_loword) diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index e18dd669b..9b2a68528 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -193,6 +193,10 @@ to see what's in there. (Note: slight variations for different compiler targets) routines, please first try again with an SD-card image instead of HostFs. It is possible that there are still small differences between HostFS and actual CBM DOS in the X16 emulator. +.. 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. + string ------ diff --git a/examples/cx16/fileseek.p8 b/examples/cx16/fileseek.p8 index b66da1bbc..e945caf05 100644 --- a/examples/cx16/fileseek.p8 +++ b/examples/cx16/fileseek.p8 @@ -32,7 +32,7 @@ main { read_last_bytes() txt.print("\nseeking to 1292 and writing a few bytes...\n") - if diskio.f_open_w("seektestfile.bin") { + if diskio.f_open_w_seek("seektestfile.bin") { diskio.f_seek_w(0, 1292) void diskio.f_write("123", 3) diskio.f_close_w() diff --git a/examples/test.p8 b/examples/test.p8 index 63d46a43c..be1a4bd9a 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,12 +1,129 @@ +%option no_sysinit %import textio +%import diskio %zeropage basicsafe main { sub start() { - if true { - txt.print("true") + str filename = "doesnotexist.xyz" + ubyte status + + + txt.print("read open...\n") + if diskio.f_open(filename) { + status = cbm.READST() + txt.print("open ok - wrong! status=") } else { - txt.print("false") + status = cbm.READST() + txt.print("open failed - good! status=") } + txt.print_ub(status) + txt.nl() + txt.print(diskio.status()) + txt.nl() + + txt.print("\nwriting the file\n") + if diskio.f_open_w(filename) { + cx16.r0 = diskio.status() + if @(cx16.r0)=='0' { + diskio.f_write("test", 4) + diskio.f_close_w() + status = cbm.READST() + txt.print("write ok! good! status=\n") + } else { + txt.print("write open error, status=") + txt.print(cx16.r0) + txt.nl() + } + } else { + status = cbm.READST() + txt.print("write open failed! wrong! status=\n") + } + txt.print_ub(status) + txt.nl() + txt.print(diskio.status()) + txt.nl() + + txt.print("\nread open...\n") + if diskio.f_open(filename) { + status = cbm.READST() + txt.print("open ok - good! status=") + } else { + status = cbm.READST() + txt.print("open failed - wrong! status=") + } + txt.print_ub(status) + txt.nl() + txt.print(diskio.status()) + txt.nl() + } +} + +main33 { + sub print_buffer() { + uword ptr = $4000 + uword firstAA = ptr + repeat 320*6 { + txt.print_ubhex(@(ptr), false) + if @(ptr)==$aa { + firstAA = ptr + break + } + ptr++ + } + txt.nl() + txt.print("first $aa is at ") + txt.print_uwhex(firstAA, true) + txt.print(" = offset ") + txt.print_uw(firstAA-$4000) + txt.nl() + } + + sub start() { + uword buffer = $4000 + sys.memset(buffer, 2000, $aa) + + print_buffer() + + void cx16.screen_mode($80, false) ; 320*240 * 256C + cx16.FB_cursor_position(0, 0) + cx16.FB_get_pixels($4000, 256) + void cx16.screen_mode(0, false) ; 320*240 * 256C + + print_buffer() + repeat { } + + + void cx16.screen_mode($80, false) ; 320*240 * 256C + ;; cx16.mouse_config2(1) + cx16.FB_cursor_position(0, 0) + + cx16.FB_set_pixels(0, 320*4) + ; expected result: exactly 12 rows of 320 pixels written + ; actual result: almost 13 rows of pixels written. + + repeat {} + +; sys.wait(9999) +; +; ; this works: +; ubyte y +; for y in 0 to 239 step 24 { +; cx16.FB_cursor_position(0, y) +; cx16.FB_set_pixels(0, 320*24) +; } +; sys.wait(120) +; +; ; this works too: +; cx16.FB_cursor_position(0,0) +; repeat 240 cx16.FB_set_pixels(0, 320) +; sys.wait(120) +; +; ; this kills the mouse pointer because it writes past the bitmap screen data +; ; expected is to write 10 times 24 rows = 240 rows of pixels, exactly 1 screen... +; cx16.FB_cursor_position(0,0) +; unroll 10 cx16.FB_set_pixels(0, 320*24) +; +; repeat {} } } diff --git a/syntax-files/Vim/prog8_builtins.vim b/syntax-files/Vim/prog8_builtins.vim index 6055ddf92..0847d77a3 100644 --- a/syntax-files/Vim/prog8_builtins.vim +++ b/syntax-files/Vim/prog8_builtins.vim @@ -647,7 +647,6 @@ syn match prog8BuiltInFunc "\" syn match prog8BuiltInFunc "\" syn match prog8BuiltInFunc "\" syn match prog8BuiltInFunc "\" -syn match prog8BuiltInFunc "\" syn match prog8BuiltInFunc "\" syn match prog8BuiltInFunc "\" syn match prog8BuiltInFunc "\"