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 "\"