diskio module: set correct read or write i/o channel every time f_read or f_write is called

This commit is contained in:
Irmen de Jong 2023-09-28 23:29:21 +02:00
parent cd40088636
commit 452e9e275f
4 changed files with 129 additions and 72 deletions

View File

@ -8,22 +8,33 @@
diskio {
%option no_symbol_prefixing
const ubyte READ_IO_CHANNEL=12
const ubyte WRITE_IO_CHANNEL=13
ubyte drivenumber = 8
sub set_drive(ubyte number) {
drivenumber = number
}
sub reset_read_channel() {
void cbm.CHKIN(READ_IO_CHANNEL)
}
sub reset_write_channel() {
cbm.CHKOUT(WRITE_IO_CHANNEL)
}
sub directory() -> bool {
; -- Prints the directory contents to the screen. Returns success.
cbm.SETNAM(1, "$")
cbm.SETLFS(12, drivenumber, 0)
cbm.SETLFS(READ_IO_CHANNEL, drivenumber, 0)
ubyte status = 1
void cbm.OPEN() ; open 12,8,0,"$"
if_cs
goto io_error
void cbm.CHKIN(12) ; use #12 as input channel
reset_read_channel()
if_cs
goto io_error
@ -61,7 +72,7 @@ diskio {
io_error:
cbm.CLRCHN() ; restore default i/o devices
cbm.CLOSE(12)
cbm.CLOSE(READ_IO_CHANNEL)
if status and status & $40 == 0 { ; bit 6=end of file
txt.print("\ni/o error, status: ")
@ -76,12 +87,12 @@ io_error:
sub diskname() -> uword {
; returns disk label name or 0 if error
cbm.SETNAM(3, "$")
cbm.SETLFS(12, diskio.drivenumber, 0)
cbm.SETLFS(READ_IO_CHANNEL, diskio.drivenumber, 0)
ubyte status = 1
void cbm.OPEN() ; open 12,8,0,"$=c"
if_cs
goto io_error
void cbm.CHKIN(12) ; use #12 as input channel
reset_read_channel()
if_cs
goto io_error
@ -106,7 +117,7 @@ io_error:
io_error:
cbm.CLRCHN()
cbm.CLOSE(12)
cbm.CLOSE(READ_IO_CHANNEL)
if status and status & $40 == 0
return 0
return diskio.list_filename
@ -150,7 +161,7 @@ io_error:
return files_found
}
; ----- iterative file lister functions (uses io channel 12) -----
; ----- iterative file lister functions (uses the read io channel) -----
sub lf_start_list(uword pattern_ptr) -> bool {
; -- start an iterative file listing with optional pattern matching.
@ -161,11 +172,11 @@ io_error:
iteration_in_progress = true
cbm.SETNAM(1, "$")
cbm.SETLFS(12, drivenumber, 0)
cbm.SETLFS(READ_IO_CHANNEL, drivenumber, 0)
void cbm.OPEN() ; open 12,8,0,"$"
if_cs
goto io_error
void cbm.CHKIN(12) ; use #12 as input channel
reset_read_channel()
if_cs
goto io_error
@ -190,7 +201,7 @@ io_error:
return false
repeat {
void cbm.CHKIN(12) ; use #12 as input channel again
reset_read_channel() ; use the input io channel again
uword nameptr = &list_filename
ubyte blocks_lsb = cbm.CHRIN()
@ -251,13 +262,13 @@ close_end:
; -- end an iterative file listing session (close channels).
if iteration_in_progress {
cbm.CLRCHN()
cbm.CLOSE(12)
cbm.CLOSE(READ_IO_CHANNEL)
iteration_in_progress = false
}
}
; ----- iterative file loader functions (uses io channel 12) -----
; ----- iterative file loader functions (uses the read io channel) -----
sub f_open(uword filenameptr) -> bool {
; -- open a file for iterative reading with f_read
@ -265,18 +276,18 @@ close_end:
f_close()
cbm.SETNAM(string.length(filenameptr), filenameptr)
cbm.SETLFS(12, drivenumber, 12) ; note: has to be 12,x,12 because otherwise f_seek doesn't work
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 {
if cbm.READST()==0 {
iteration_in_progress = true
void cbm.CHKIN(12) ; use #12 as input channel
reset_read_channel()
if_cc {
void cbm.CHRIN() ; read first byte to test for file not found
if not cbm.READST() {
cbm.CLOSE(12) ; close file because we already consumed first byte
cbm.CLOSE(READ_IO_CHANNEL) ; close file because we already consumed first byte
void cbm.OPEN() ; re-open the file
void cbm.CHKIN(12)
cbm.CLRCHN() ; reset default i/o channels
return true
}
}
@ -294,6 +305,7 @@ close_end:
if not iteration_in_progress or not num_bytes
return 0
reset_read_channel()
list_blocks = 0 ; we reuse this variable for the total number of bytes read
; commander X16 supports fast block-read via macptr() kernal call
@ -352,6 +364,7 @@ m_in_buffer sta $ffff
if not iteration_in_progress
return 0
reset_read_channel()
uword total_read = 0
while not cbm.READST() {
cx16.r0 = f_read(bufferpointer, 256)
@ -370,8 +383,7 @@ m_in_buffer sta $ffff
%asm {{
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldx #12
jsr cbm.CHKIN ; use channel 12 again for input
jsr reset_read_channel
ldy #0
_loop jsr cbm.CHRIN
sta (P8ZP_SCRATCH_W1),y
@ -392,25 +404,23 @@ _end rts
; -- end an iterative file loading session (close channels).
if iteration_in_progress {
cbm.CLRCHN()
cbm.CLOSE(12)
cbm.CLOSE(READ_IO_CHANNEL)
iteration_in_progress = false
}
}
; ----- iterative file writing functions (uses io channel 13) -----
; ----- 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()
cbm.SETNAM(string.length(filenameptr), filenameptr)
cbm.SETLFS(13, drivenumber, 1)
cbm.SETLFS(WRITE_IO_CHANNEL, drivenumber, 1)
void cbm.OPEN() ; open 13,8,1,"filename"
if_cc {
cbm.CHKOUT(13) ; use #13 as output channel
if_cc
return not cbm.READST()
}
f_close_w()
return false
}
@ -418,7 +428,7 @@ _end rts
sub f_write(uword bufferpointer, uword num_bytes) -> bool {
; -- write the given number of bytes to the currently open file
if num_bytes!=0 {
cbm.CHKOUT(13) ; use #13 as output channel again
reset_write_channel()
repeat num_bytes {
cbm.CHROUT(@(bufferpointer))
bufferpointer++
@ -431,7 +441,7 @@ _end rts
sub f_close_w() {
; -- end an iterative file writing session (close channels).
cbm.CLRCHN()
cbm.CLOSE(13)
cbm.CLOSE(WRITE_IO_CHANNEL)
}
@ -693,11 +703,11 @@ internal_vload:
cx16.r12 = reversebuffer + MAX_PATH_LEN-1
@(cx16.r12)=0
cbm.SETNAM(3, "$=c")
cbm.SETLFS(12, diskio.drivenumber, 0)
cbm.SETLFS(READ_IO_CHANNEL, diskio.drivenumber, 0)
void cbm.OPEN() ; open 12,8,0,"$=c"
if_cs
goto io_error
void cbm.CHKIN(12) ; use #12 as input channel
reset_read_channel()
if_cs
goto io_error
@ -734,7 +744,7 @@ internal_vload:
io_error:
cbm.CLRCHN()
cbm.CLOSE(12)
cbm.CLOSE(READ_IO_CHANNEL)
if status and status & $40 == 0
return 0
if @(cx16.r12)==0 {
@ -767,7 +777,7 @@ io_error:
sub f_seek(uword pos_hiword, uword pos_loword) {
; -- seek in the reading file opened with f_open, to the given 32-bits position
ubyte[6] command = ['p',0,0,0,0,0]
command[1] = 12 ; f_open uses channel 12
command[1] = READ_IO_CHANNEL ; f_open uses the read io channel
command[2] = lsb(pos_loword)
command[3] = msb(pos_loword)
command[4] = lsb(pos_hiword)
@ -777,14 +787,14 @@ io_error:
cbm.SETLFS(15, drivenumber, 15)
void cbm.OPEN()
cbm.CLOSE(15)
void cbm.CHKIN(12) ; back to the channel that f_open uses
reset_read_channel() ; back to the read io channel
}
; NOTE: f_seek_w() doesn't work reliably right now. I only manage to corrupt the fat32 filesystem on the sdcard with it...
; 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
; diskio.f_seek.command[1] = 13 ; f_open_w uses channel 13
; diskio.f_seek.command[1] = WRITE_IO_CHANNEL ; f_open_w uses the write io channel
; diskio.f_seek.command[2] = lsb(pos_loword)
; diskio.f_seek.command[3] = msb(pos_loword)
; diskio.f_seek.command[4] = lsb(pos_hiword)

View File

@ -7,22 +7,33 @@
diskio {
%option no_symbol_prefixing
const ubyte READ_IO_CHANNEL=12
const ubyte WRITE_IO_CHANNEL=13
ubyte drivenumber = 8
sub set_drive(ubyte number) {
drivenumber = number
}
sub reset_read_channel() {
void cbm.CHKIN(READ_IO_CHANNEL)
}
sub reset_write_channel() {
cbm.CHKOUT(WRITE_IO_CHANNEL)
}
sub directory() -> bool {
; -- Prints the directory contents to the screen. Returns success.
cbm.SETNAM(1, "$")
cbm.SETLFS(12, drivenumber, 0)
cbm.SETLFS(READ_IO_CHANNEL, drivenumber, 0)
ubyte status = 1
void cbm.OPEN() ; open 12,8,0,"$"
if_cs
goto io_error
void cbm.CHKIN(12) ; use #12 as input channel
reset_read_channel()
if_cs
goto io_error
@ -60,7 +71,7 @@ diskio {
io_error:
cbm.CLRCHN() ; restore default i/o devices
cbm.CLOSE(12)
cbm.CLOSE(READ_IO_CHANNEL)
if status and status & $40 == 0 { ; bit 6=end of file
txt.print("\ni/o error, status: ")
@ -76,12 +87,12 @@ io_error:
; -- Returns pointer to disk name string or 0 if failure.
cbm.SETNAM(1, "$")
cbm.SETLFS(12, drivenumber, 0)
cbm.SETLFS(READ_IO_CHANNEL, drivenumber, 0)
ubyte okay = false
void cbm.OPEN() ; open 12,8,0,"$"
if_cs
goto io_error
void cbm.CHKIN(12) ; use #12 as input channel
reset_read_channel()
if_cs
goto io_error
@ -108,7 +119,7 @@ io_error:
io_error:
cbm.CLRCHN() ; restore default i/o devices
cbm.CLOSE(12)
cbm.CLOSE(READ_IO_CHANNEL)
if okay
return &list_filename
return 0
@ -152,7 +163,7 @@ io_error:
return files_found
}
; ----- iterative file lister functions (uses io channel 12) -----
; ----- iterative file lister functions (uses the read io channel) -----
sub lf_start_list(uword pattern_ptr) -> bool {
; -- start an iterative file listing with optional pattern matching.
@ -163,11 +174,11 @@ io_error:
iteration_in_progress = true
cbm.SETNAM(1, "$")
cbm.SETLFS(12, drivenumber, 0)
cbm.SETLFS(READ_IO_CHANNEL, drivenumber, 0)
void cbm.OPEN() ; open 12,8,0,"$"
if_cs
goto io_error
void cbm.CHKIN(12) ; use #12 as input channel
reset_read_channel()
if_cs
goto io_error
@ -192,7 +203,7 @@ io_error:
return false
repeat {
void cbm.CHKIN(12) ; use #12 as input channel again
reset_read_channel() ; use the input io channel again
uword nameptr = &list_filename
ubyte blocks_lsb = cbm.CHRIN()
@ -253,13 +264,13 @@ close_end:
; -- end an iterative file listing session (close channels).
if iteration_in_progress {
cbm.CLRCHN()
cbm.CLOSE(12)
cbm.CLOSE(READ_IO_CHANNEL)
iteration_in_progress = false
}
}
; ----- iterative file loader functions (uses io channel 12) -----
; ----- iterative file loader functions (uses the input io channel) -----
sub f_open(uword filenameptr) -> bool {
; -- open a file for iterative reading with f_read
@ -267,18 +278,18 @@ close_end:
f_close()
cbm.SETNAM(string.length(filenameptr), filenameptr)
cbm.SETLFS(12, drivenumber, 12) ; note: has to be 12,x,12 because otherwise f_seek doesn't work
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 {
if cbm.READST()==0 {
iteration_in_progress = true
void cbm.CHKIN(12) ; use #12 as input channel
reset_read_channel()
if_cc {
void cbm.CHRIN() ; read first byte to test for file not found
if not cbm.READST() {
cbm.CLOSE(12) ; close file because we already consumed first byte
cbm.CLOSE(READ_IO_CHANNEL) ; close file because we already consumed first byte
void cbm.OPEN() ; re-open the file
void cbm.CHKIN(12)
cbm.CLRCHN() ; reset default i/o channels
return true
}
}
@ -294,6 +305,7 @@ close_end:
if not iteration_in_progress or not num_bytes
return 0
reset_read_channel()
list_blocks = 0 ; we reuse this variable for the total number of bytes read
%asm {{
@ -328,6 +340,7 @@ m_in_buffer sta $ffff
if not iteration_in_progress
return 0
reset_read_channel()
uword total_read = 0
while not cbm.READST() {
cx16.r0 = f_read(bufferpointer, 256)
@ -346,8 +359,7 @@ m_in_buffer sta $ffff
%asm {{
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldx #12
jsr cbm.CHKIN ; use channel 12 again for input
jsr reset_read_channel
ldy #0
_loop jsr cbm.CHRIN
sta (P8ZP_SCRATCH_W1),y
@ -368,25 +380,23 @@ _end rts
; -- end an iterative file loading session (close channels).
if iteration_in_progress {
cbm.CLRCHN()
cbm.CLOSE(12)
cbm.CLOSE(READ_IO_CHANNEL)
iteration_in_progress = false
}
}
; ----- iterative file writing functions (uses io channel 13) -----
; ----- 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()
cbm.SETNAM(string.length(filenameptr), filenameptr)
cbm.SETLFS(13, drivenumber, 1)
cbm.SETLFS(WRITE_IO_CHANNEL, drivenumber, 1)
void cbm.OPEN() ; open 13,8,1,"filename"
if_cc {
cbm.CHKOUT(13) ; use #13 as output channel
if_cc
return not cbm.READST()
}
f_close_w()
return false
}
@ -394,7 +404,7 @@ _end rts
sub f_write(uword bufferpointer, uword num_bytes) -> bool {
; -- write the given number of bytes to the currently open file
if num_bytes!=0 {
cbm.CHKOUT(13) ; use #13 as output channel again
reset_write_channel()
repeat num_bytes {
cbm.CHROUT(@(bufferpointer))
bufferpointer++
@ -407,7 +417,7 @@ _end rts
sub f_close_w() {
; -- end an iterative file writing session (close channels).
cbm.CLRCHN()
cbm.CLOSE(13)
cbm.CLOSE(WRITE_IO_CHANNEL)
}

View File

@ -1,9 +1,8 @@
TODO
====
- clean up the active file channel assumptions in diskio (basically do chkin every time and not in f_open?)
- return the file channel number from f_open and f_open_w instead of just true (so user can change it and set it back if they want instead of relying on the magic numbers 12 and 13)
OR just add routines to set it back to 12/13 so no tracking has to occur by the user at all
- fix c64 diskio.f_write optimizer issue (in test.p8)
- why is petscii \n translated to $8d and not $0d? and \r IS translated to $0d?
- add a compiler switch to replace all calls to the math word mul routine on the X16 by the verafx call instead.
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
- [on branch: ir-less-branch-opcodes] IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction

View File

@ -1,23 +1,61 @@
%import diskio
%import textio
%import math
;%import math
;%import verafx
%zeropage basicsafe
%option no_sysinit
main {
sub start() {
ubyte[256] buf
void diskio.delete("lines.txt")
if diskio.f_open_w("@:lines.txt") {
txt.print("writing...\n")
repeat 10 {
if not diskio.f_write("line\r", 5) {
diskio.f_close_w()
txt.print("write error\n")
break
}
}
diskio.f_close_w()
}
txt.print("\nwritten.\n\n")
txt.print_uw(math.mul16_last_upper())
txt.nl()
uword value1=5678
uword value2=9999
uword result = value1*value2
uword upper16 = math.mul16_last_upper()
txt.print_uw(result)
txt.spc()
txt.print_uw(upper16)
txt.nl()
if diskio.f_open("lines.txt") {
txt.print("reading...\n")
repeat {
if diskio.f_readline(buf)==0 {
diskio.f_close()
txt.print("readline is 0\n")
break
}
if cbm.READST() {
txt.print(diskio.status())
diskio.f_close()
break
}
txt.print(buf)
txt.nl()
}
diskio.f_close()
} else {
txt.print(diskio.status())
}
txt.print("\ndone.\n")
; txt.print_uw(math.mul16_last_upper())
; txt.nl()
; uword value1=5678
; uword value2=9999
; uword result = value1*value2
; uword upper16 = math.mul16_last_upper()
; txt.print_uw(result)
; txt.spc()
; txt.print_uw(upper16)
; txt.nl()
; const word MULTIPLIER = 431