From f3e3311598a8e1868ec4c40db543f428b04d9438 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 21 May 2024 23:14:25 +0200 Subject: [PATCH] added diskio.f_tell() and f_tell32() on the cx16 target --- compiler/res/prog8lib/cx16/diskio.p8 | 63 +++++++++++++++++++++++++++- examples/test.p8 | 41 ++++++++++++++---- 2 files changed, 94 insertions(+), 10 deletions(-) diff --git a/compiler/res/prog8lib/cx16/diskio.p8 b/compiler/res/prog8lib/cx16/diskio.p8 index 4e8d35483..896910a36 100644 --- a/compiler/res/prog8lib/cx16/diskio.p8 +++ b/compiler/res/prog8lib/cx16/diskio.p8 @@ -688,7 +688,7 @@ io_error: } sub send_command(uword commandptr) { - ; -- send a dos command to the drive + ; -- send a dos command to the drive (don't read any response) cbm.SETNAM(string.length(commandptr), commandptr) cbm.SETLFS(15, drivenumber, 15) void cbm.OPEN() @@ -869,7 +869,6 @@ io_error: command[3] = msb(pos_loword) command[4] = lsb(pos_hiword) command[5] = msb(pos_hiword) - send_command: cbm.SETNAM(sizeof(command), &command) cbm.SETLFS(15, drivenumber, 15) void cbm.OPEN() @@ -892,4 +891,64 @@ io_error: reset_write_channel() ; back to the write io channel } + asmsub f_tell32() -> uword @R0, uword @R1, uword @R2, uword @R3 { + ; -- Returns the current read position in R0 and R1 (low + high words) + ; and the file size in R1 and R2 (low + high words). + ; Returns 0 as size if the command is not supported by the DOS implementation/version. + %asm {{ + jmp internal_f_tell + }} + } + + asmsub f_tell() -> uword @R0, uword @R2 { + ; -- 16 bits version of f_tell32() because most file sizes will be <64Kb. + ; Returns the current read position in R0 and the file size in R2 (R1 is not used in this case). Both in bytes. + ; Returns 0 as size if the command is not supported by the DOS implementation/version. + %asm {{ + jmp internal_f_tell + }} + } + + sub internal_f_tell(ubyte channel) { + ; gets the (32 bits) position + file size of the given open channel + ubyte[2] command = ['t',0] + command[1] = READ_IO_CHANNEL ; f_open uses this secondary address + cbm.SETNAM(sizeof(command), &command) + cbm.SETLFS(15, drivenumber, 15) + void cbm.OPEN() + void cbm.CHKIN(15) ; use #15 as input channel + bool success=false + ; valid response starts with "07," followed by hex notations of the position and filesize + if cbm.CHRIN()=='0' and cbm.CHRIN()=='7' and cbm.CHRIN()==',' { + cx16.r1 = read4hex() + cx16.r0 = read4hex() ; position in R1:R0 + void cbm.CHRIN() ; separator space + cx16.r3 = read4hex() + cx16.r2 = read4hex() ; filesize in R3:R2 + success = true + } + + while cbm.READST()==0 { + cx16.r5L = cbm.CHRIN() + if cx16.r5L=='\r' or cx16.r5L=='\n' + break + } + + cbm.CLOSE(15) + reset_read_channel() ; back to the read io channel + if success + return + + cx16.r0 = cx16.r1 = cx16.r2 = cx16.r3 = 0 + + sub read4hex() -> uword { + str hex = "0000" + hex[0] = cbm.CHRIN() + hex[1] = cbm.CHRIN() + hex[2] = cbm.CHRIN() + hex[3] = cbm.CHRIN() + return conv.hex2uword(hex) + } + } + } diff --git a/examples/test.p8 b/examples/test.p8 index 2d739a1a6..8ea1766c5 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,15 +1,40 @@ +%import diskio +%import textio %zeropage basicsafe main { sub start() { - ubyte @requirezp b1 - ubyte @zp b2 - ubyte b3 - ubyte @nozp b4 + if diskio.f_open("tehtriz.asm") { + repeat 10 { + void diskio.f_read($6000, 9999) + } + uword pl, ph, sl, sh + pl, ph, sl, sh = diskio.f_tell32() - b1++ - b2++ - b3++ - b4++ + txt.print("\npos: ") + txt.print_uwhex(ph, true) + txt.print_uwhex(pl, false) + txt.print("\nsize: ") + txt.print_uwhex(sh, true) + txt.print_uwhex(sl, false) + txt.nl() + + diskio.f_close() + } + + if diskio.f_open("test.p8ir") { + repeat 5 { + void diskio.f_read($6000, 999) + } + + pl, sl = diskio.f_tell() + txt.print("\npos16: ") + txt.print_uwhex(pl, true) + txt.print("\nsize16: ") + txt.print_uwhex(sl, true) + txt.nl() + + diskio.f_close() + } } }