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!
This commit is contained in:
Irmen de Jong 2023-11-12 20:40:17 +01:00
parent d22359b6e7
commit aa949165c7
5 changed files with 152 additions and 20 deletions

View File

@ -280,9 +280,11 @@ close_end:
; ----- iterative file loader functions (uses the read io channel) ----- ; ----- 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 ; -- open a file for iterative reading with f_read
; note: only a single iteration loop can be active at a time! ; 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() f_close()
cbm.SETNAM(string.length(filenameptr), filenameptr) cbm.SETNAM(string.length(filenameptr), filenameptr)
@ -421,24 +423,34 @@ _end rts
; ----- iterative file writing functions (uses write io channel) ----- ; ----- iterative file writing functions (uses write io channel) -----
sub f_open_w(uword filenameptr) -> bool { sub f_open_w(str filename) -> bool {
; -- open a file for iterative writing with f_write ; -- Open a file for iterative writing with f_write
f_close_w() ; 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 sub f_open_w_seek(str filename) -> bool {
list_filename = filenameptr ; -- Open an existing file for iterative writing with f_write, and seeking with f_seek_w.
cx16.r0L = string.append(list_filename, ",s,m") 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.SETNAM(cx16.r0L, list_filename)
cbm.SETLFS(WRITE_IO_CHANNEL, drivenumber, WRITE_IO_CHANNEL) cbm.SETLFS(WRITE_IO_CHANNEL, drivenumber, WRITE_IO_CHANNEL)
void cbm.OPEN() ; open 13,8,13,"filename" void cbm.OPEN() ; open 13,8,13,"filename"
if_cc { if_cc {
if cbm.READST()==0 { return not cbm.READST()
; check the drive status to see if it has actually succeeded
cx16.r0 = status()
reset_write_channel()
if @(cx16.r0)=='0'
return true
}
} }
f_close_w() f_close_w()
return false return false
@ -821,7 +833,7 @@ io_error:
sub f_seek_w(uword pos_hiword, uword pos_loword) { 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[1] = WRITE_IO_CHANNEL ; f_open_w uses this secondary address
diskio.f_seek.command[2] = lsb(pos_loword) diskio.f_seek.command[2] = lsb(pos_loword)
diskio.f_seek.command[3] = msb(pos_loword) diskio.f_seek.command[3] = msb(pos_loword)

View File

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

View File

@ -32,7 +32,7 @@ main {
read_last_bytes() read_last_bytes()
txt.print("\nseeking to 1292 and writing a few bytes...\n") 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) diskio.f_seek_w(0, 1292)
void diskio.f_write("123", 3) void diskio.f_write("123", 3)
diskio.f_close_w() diskio.f_close_w()

View File

@ -1,12 +1,129 @@
%option no_sysinit
%import textio %import textio
%import diskio
%zeropage basicsafe %zeropage basicsafe
main { main {
sub start() { sub start() {
if true { str filename = "doesnotexist.xyz"
txt.print("true") ubyte status
txt.print("read open...\n")
if diskio.f_open(filename) {
status = cbm.READST()
txt.print("open ok - wrong! status=")
} else { } 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 {}
} }
} }

View File

@ -647,7 +647,6 @@ syn match prog8BuiltInFunc "\<cx16\.FB_init\>"
syn match prog8BuiltInFunc "\<cx16\.FB_get_info\>" syn match prog8BuiltInFunc "\<cx16\.FB_get_info\>"
syn match prog8BuiltInFunc "\<cx16\.FB_set_palette\>" syn match prog8BuiltInFunc "\<cx16\.FB_set_palette\>"
syn match prog8BuiltInFunc "\<cx16\.FB_cursor_position\>" syn match prog8BuiltInFunc "\<cx16\.FB_cursor_position\>"
syn match prog8BuiltInFunc "\<cx16\.FB_cursor_position2\>"
syn match prog8BuiltInFunc "\<cx16\.FB_cursor_next_line\>" syn match prog8BuiltInFunc "\<cx16\.FB_cursor_next_line\>"
syn match prog8BuiltInFunc "\<cx16\.FB_get_pixel\>" syn match prog8BuiltInFunc "\<cx16\.FB_get_pixel\>"
syn match prog8BuiltInFunc "\<cx16\.FB_get_pixels\>" syn match prog8BuiltInFunc "\<cx16\.FB_get_pixels\>"