From 0f26b39997919eb8603ddcfe49767f35729195f1 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 17 Dec 2023 21:21:55 +0100 Subject: [PATCH] improve diskio error handling and device not found errors for instance if you set drivenumber to 9 without having a second drive connected, it used to hang in various routines --- compiler/res/prog8lib/cx16/diskio.p8 | 41 ++++++++++++++-------------- compiler/res/prog8lib/diskio.p8 | 38 ++++++++++++++------------ docs/source/todo.rst | 4 +-- 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/compiler/res/prog8lib/cx16/diskio.p8 b/compiler/res/prog8lib/cx16/diskio.p8 index 56cf8f8bd..56aba0812 100644 --- a/compiler/res/prog8lib/cx16/diskio.p8 +++ b/compiler/res/prog8lib/cx16/diskio.p8 @@ -12,6 +12,7 @@ %import textio +%import conv %import string %import syslib @@ -41,8 +42,6 @@ diskio { if_cs goto io_error reset_read_channel() - if_cs - goto io_error repeat 4 { void cbm.CHRIN() ; skip the 4 prologue bytes @@ -99,8 +98,6 @@ io_error: if_cs goto io_error reset_read_channel() - if_cs - goto io_error while cbm.CHRIN()!='"' { ; skip up to entry name @@ -184,8 +181,6 @@ io_error: if_cs goto io_error reset_read_channel() - if_cs - goto io_error repeat 4 { void cbm.CHRIN() ; skip the 4 prologue bytes @@ -195,6 +190,7 @@ io_error: return true io_error: + cbm.CLOSE(READ_IO_CHANNEL) lf_end_list() return false } @@ -290,21 +286,20 @@ close_end: cbm.SETLFS(READ_IO_CHANNEL, drivenumber, READ_IO_CHANNEL) ; note: has to be Channel,x,Channel because otherwise f_seek doesn't work void cbm.OPEN() ; open 12,8,12,"filename" if_cc { + reset_read_channel() if cbm.READST()==0 { iteration_in_progress = true - reset_read_channel() - if_cc { - void cbm.CHRIN() ; read first byte to test for file not found - if not cbm.READST() { - cbm.CLOSE(READ_IO_CHANNEL) ; close file because we already consumed first byte - void cbm.OPEN() ; re-open the file - cbm.CLRCHN() ; reset default i/o channels - return true - } + void cbm.CHRIN() ; read first byte to test for file not found + if cbm.READST()==0 { + cbm.CLOSE(READ_IO_CHANNEL) ; close file because we already consumed first byte + void cbm.OPEN() ; re-open the file + cbm.CLRCHN() ; reset default i/o channels + return true } } } f_close() + cbm.CLOSE(READ_IO_CHANNEL) return false } @@ -451,6 +446,7 @@ _end rts if_cc { return not cbm.READST() } + cbm.CLOSE(WRITE_IO_CHANNEL) f_close_w() return false } @@ -494,6 +490,14 @@ no_mciout: sub status() -> uword { ; -- retrieve the disk drive's current status message + str device_not_present_error = "device not present #xx" + if cbm.READST()==128 { + device_not_present_error[len(device_not_present_error)-2] = 0 + conv.str_ub(drivenumber) + void string.copy(conv.string_out, &device_not_present_error+len(device_not_present_error)-2) + return device_not_present_error + } + uword messageptr = &list_filename cbm.SETNAM(0, list_filename) cbm.SETLFS(15, drivenumber, 15) @@ -501,8 +505,6 @@ no_mciout: if_cs goto io_error void cbm.CHKIN(15) ; use #15 as input channel - if_cs - goto io_error while not cbm.READST() { cx16.r5L = cbm.CHRIN() @@ -519,7 +521,8 @@ done: return list_filename io_error: - list_filename = "?disk error" + cbm.CLOSE(15) + list_filename = "io error" goto done } @@ -748,8 +751,6 @@ internal_vload: if_cs goto io_error reset_read_channel() - if_cs - goto io_error repeat 6 { void cbm.CHRIN() diff --git a/compiler/res/prog8lib/diskio.p8 b/compiler/res/prog8lib/diskio.p8 index 5ee78fd17..923bbb5f5 100644 --- a/compiler/res/prog8lib/diskio.p8 +++ b/compiler/res/prog8lib/diskio.p8 @@ -1,6 +1,7 @@ ; C64/C128 disk drive I/O routines. %import textio +%import conv %import string %import syslib @@ -30,8 +31,6 @@ diskio { if_cs goto io_error reset_read_channel() - if_cs - goto io_error repeat 4 { void cbm.CHRIN() ; skip the 4 prologue bytes @@ -89,8 +88,6 @@ io_error: if_cs goto io_error reset_read_channel() - if_cs - goto io_error while cbm.CHRIN()!='"' { ; skip up to entry name @@ -175,8 +172,6 @@ io_error: if_cs goto io_error reset_read_channel() - if_cs - goto io_error repeat 4 { void cbm.CHRIN() ; skip the 4 prologue bytes @@ -186,6 +181,7 @@ io_error: return true io_error: + cbm.CLOSE(READ_IO_CHANNEL) lf_end_list() return false } @@ -281,21 +277,20 @@ close_end: cbm.SETLFS(READ_IO_CHANNEL, drivenumber, READ_IO_CHANNEL) ; note: has to be Channel,x,Channel because otherwise f_seek doesn't work void cbm.OPEN() ; open 12,8,12,"filename" if_cc { + reset_read_channel() if cbm.READST()==0 { iteration_in_progress = true - reset_read_channel() - if_cc { - void cbm.CHRIN() ; read first byte to test for file not found - if not cbm.READST() { - cbm.CLOSE(READ_IO_CHANNEL) ; close file because we already consumed first byte - void cbm.OPEN() ; re-open the file - cbm.CLRCHN() ; reset default i/o channels - return true - } + void cbm.CHRIN() ; read first byte to test for file not found + if cbm.READST()==0 { + cbm.CLOSE(READ_IO_CHANNEL) ; close file because we already consumed first byte + void cbm.OPEN() ; re-open the file + cbm.CLRCHN() ; reset default i/o channels + return true } } } f_close() + cbm.CLOSE(READ_IO_CHANNEL) return false } @@ -402,6 +397,7 @@ _end rts void cbm.OPEN() ; open 13,8,1,"filename" if_cc return not cbm.READST() + cbm.CLOSE(WRITE_IO_CHANNEL) f_close_w() return false } @@ -430,6 +426,13 @@ _end rts sub status() -> uword { ; -- retrieve the disk drive's current status message + str device_not_present_error = "device not present #xx" + if cbm.READST()==128 { + device_not_present_error[len(device_not_present_error)-2] = 0 + conv.str_ub(drivenumber) + void string.copy(conv.string_out, &device_not_present_error+len(device_not_present_error)-2) + return device_not_present_error + } uword messageptr = &list_filename cbm.SETNAM(0, list_filename) cbm.SETLFS(15, drivenumber, 15) @@ -437,8 +440,6 @@ _end rts if_cs goto io_error void cbm.CHKIN(15) ; use #15 as input channel - if_cs - goto io_error while not cbm.READST() { cx16.r5L = cbm.CHRIN() @@ -455,7 +456,8 @@ done: return list_filename io_error: - list_filename = "?disk error" + cbm.CLOSE(15) + list_filename = "io error" goto done } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 4a304be3f..70b2f827e 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,8 @@ TODO ==== - 'audio' or 'kaudio' or 'romutils' to contain prog8 definitions for the rom bank 10 audio routines - and a wrapper to call x16edit with costomization + or just fold it all into cx16 syslib? + including a wrapper to call x16edit with and without customization - verafx vram-vram copy routine? set the cache fill and cache write bits in fx ctrl, set one data port's increment to 1 and the other one to 4, @@ -21,7 +22,6 @@ Future Things and Ideas Compiler: - (after shortcircuit is in:) What happens when we make all subs return a boolean not as ubyte in A, but in the cpu's Carry flag? -- What happens when we keep the BOOL type around until in codegen? (so, get rid of Boolean->ubyte and boolean remover) - Multidimensional arrays and chained indexing, purely as syntactic sugar over regular arrays. - make a form of "manual generics" possible like: varsub routine(T arg)->T where T is expanded to a specific type (this is already done hardcoded for several of the builtin functions)