mirror of
https://github.com/irmen/prog8.git
synced 2025-01-26 19:30:59 +00:00
added cx16diskio.f_seek() function to seek to a position in an opened file
f_open uses channel 12 now, f_open_w uses 13
This commit is contained in:
parent
7ebcb219d6
commit
f870e4965a
@ -35,8 +35,8 @@ cx16diskio {
|
||||
return $2000 * (cx16.getrambank() - startbank) + endaddress - startaddress
|
||||
}
|
||||
|
||||
asmsub vload(str name @R0, ubyte device @Y, ubyte bank @A, uword address @R1) -> ubyte @A {
|
||||
; -- like the basic command VLOAD "filename",device,bank,address
|
||||
asmsub vload(str name @R0, ubyte drivenumber @Y, ubyte bank @A, uword address @R1) -> ubyte @A {
|
||||
; -- like the basic command VLOAD "filename",drivenumber,bank,address
|
||||
; loads a file into Vera's video memory in the given bank:address, returns success in A
|
||||
; the file has to have the usual 2 byte header (which will be skipped)
|
||||
%asm {{
|
||||
@ -77,8 +77,8 @@ internal_vload:
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub vload_raw(str name @R0, ubyte device @Y, ubyte bank @A, uword address @R1) -> ubyte @A {
|
||||
; -- like the basic command BVLOAD "filename",device,bank,address
|
||||
asmsub vload_raw(str name @R0, ubyte drivenumber @Y, ubyte bank @A, uword address @R1) -> ubyte @A {
|
||||
; -- like the basic command BVLOAD "filename",drivenumber,bank,address
|
||||
; loads a file into Vera's video memory in the given bank:address, returns success in A
|
||||
; the file is read fully including the first two bytes.
|
||||
%asm {{
|
||||
@ -104,7 +104,7 @@ internal_vload:
|
||||
num_bytes--
|
||||
}
|
||||
|
||||
void c64.CHKIN(11) ; use #11 as input channel again
|
||||
void c64.CHKIN(12) ; use #12 as input channel again
|
||||
|
||||
; commander X16 supports fast block-read via macptr() kernal call
|
||||
uword size
|
||||
@ -191,7 +191,7 @@ m_in_buffer sta $ffff
|
||||
diskio.list_filename[1] = 'd'
|
||||
diskio.list_filename[2] = ':'
|
||||
void string.copy(path, &diskio.list_filename+3)
|
||||
void diskio.send_command(drivenumber, diskio.list_filename)
|
||||
diskio.send_command(drivenumber, diskio.list_filename)
|
||||
}
|
||||
|
||||
sub mkdir(ubyte drivenumber, str name) {
|
||||
@ -200,7 +200,7 @@ m_in_buffer sta $ffff
|
||||
diskio.list_filename[1] = 'd'
|
||||
diskio.list_filename[2] = ':'
|
||||
void string.copy(name, &diskio.list_filename+3)
|
||||
void diskio.send_command(drivenumber, diskio.list_filename)
|
||||
diskio.send_command(drivenumber, diskio.list_filename)
|
||||
}
|
||||
|
||||
sub rmdir(ubyte drivenumber, str name) {
|
||||
@ -212,7 +212,7 @@ m_in_buffer sta $ffff
|
||||
diskio.list_filename[1] = 'd'
|
||||
diskio.list_filename[2] = ':'
|
||||
void string.copy(name, &diskio.list_filename+3)
|
||||
void diskio.send_command(drivenumber, diskio.list_filename)
|
||||
diskio.send_command(drivenumber, diskio.list_filename)
|
||||
}
|
||||
|
||||
sub relabel(ubyte drivenumber, str name) {
|
||||
@ -222,6 +222,33 @@ m_in_buffer sta $ffff
|
||||
diskio.list_filename[2] = 'h'
|
||||
diskio.list_filename[3] = ':'
|
||||
void string.copy(name, &diskio.list_filename+4)
|
||||
void diskio.send_command(drivenumber, diskio.list_filename)
|
||||
diskio.send_command(drivenumber, diskio.list_filename)
|
||||
}
|
||||
|
||||
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[2] = lsb(pos_loword)
|
||||
command[3] = msb(pos_loword)
|
||||
command[4] = lsb(pos_hiword)
|
||||
command[5] = msb(pos_hiword)
|
||||
send_command:
|
||||
c64.SETNAM(sizeof(command), &command)
|
||||
c64.SETLFS(15, diskio.last_drivenumber, 15)
|
||||
void c64.OPEN()
|
||||
c64.CLOSE(15)
|
||||
diskio.have_first_byte = false
|
||||
}
|
||||
|
||||
; TODO see if we can get this to work as well:
|
||||
; 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
|
||||
; cx16diskio.f_seek.command[1] = 1 ; f_open_w uses secondary channel 1
|
||||
; cx16diskio.f_seek.command[2] = poslo
|
||||
; cx16diskio.f_seek.command[3] = posmidlo
|
||||
; cx16diskio.f_seek.command[4] = posmidhi
|
||||
; cx16diskio.f_seek.command[5] = poshi
|
||||
; goto cx16diskio.f_seek.send_command
|
||||
; }
|
||||
}
|
||||
|
@ -10,12 +10,12 @@ diskio {
|
||||
; -- Prints the directory contents of disk drive 8-11 to the screen. Returns success.
|
||||
|
||||
c64.SETNAM(1, "$")
|
||||
c64.SETLFS(13, drivenumber, 0)
|
||||
c64.SETLFS(12, drivenumber, 0)
|
||||
ubyte status = 1
|
||||
void c64.OPEN() ; open 13,8,0,"$"
|
||||
void c64.OPEN() ; open 12,8,0,"$"
|
||||
if_cs
|
||||
goto io_error
|
||||
void c64.CHKIN(13) ; use #13 as input channel
|
||||
void c64.CHKIN(12) ; use #12 as input channel
|
||||
if_cs
|
||||
goto io_error
|
||||
|
||||
@ -53,7 +53,7 @@ diskio {
|
||||
|
||||
io_error:
|
||||
c64.CLRCHN() ; restore default i/o devices
|
||||
c64.CLOSE(13)
|
||||
c64.CLOSE(12)
|
||||
|
||||
if status and status & $40 == 0 { ; bit 6=end of file
|
||||
txt.print("\ni/o error, status: ")
|
||||
@ -69,12 +69,12 @@ io_error:
|
||||
; -- Returns pointer to disk name string or 0 if failure.
|
||||
|
||||
c64.SETNAM(1, "$")
|
||||
c64.SETLFS(13, drivenumber, 0)
|
||||
c64.SETLFS(12, drivenumber, 0)
|
||||
ubyte okay = false
|
||||
void c64.OPEN() ; open 13,8,0,"$"
|
||||
void c64.OPEN() ; open 12,8,0,"$"
|
||||
if_cs
|
||||
goto io_error
|
||||
void c64.CHKIN(13) ; use #13 as input channel
|
||||
void c64.CHKIN(12) ; use #12 as input channel
|
||||
if_cs
|
||||
goto io_error
|
||||
|
||||
@ -96,7 +96,7 @@ io_error:
|
||||
|
||||
io_error:
|
||||
c64.CLRCHN() ; restore default i/o devices
|
||||
c64.CLOSE(13)
|
||||
c64.CLOSE(12)
|
||||
if okay
|
||||
return &list_filename
|
||||
return 0
|
||||
@ -109,6 +109,7 @@ io_error:
|
||||
bool iteration_in_progress = false
|
||||
ubyte @zp first_byte
|
||||
bool have_first_byte
|
||||
ubyte last_drivenumber = 8 ; which drive was last used for a f_open operation?
|
||||
str list_filetype = "???" ; prg, seq, dir
|
||||
str list_filename = "?" * 50
|
||||
|
||||
@ -249,7 +250,7 @@ close_end:
|
||||
}
|
||||
|
||||
|
||||
; ----- iterative file loader functions (uses io channel 11) -----
|
||||
; ----- iterative file loader functions (uses io channel 12) -----
|
||||
|
||||
sub f_open(ubyte drivenumber, uword filenameptr) -> bool {
|
||||
; -- open a file for iterative reading with f_read
|
||||
@ -257,13 +258,14 @@ close_end:
|
||||
f_close()
|
||||
|
||||
c64.SETNAM(string.length(filenameptr), filenameptr)
|
||||
c64.SETLFS(11, drivenumber, 0)
|
||||
void c64.OPEN() ; open 11,8,0,"filename"
|
||||
c64.SETLFS(12, drivenumber, 12) ; note: has to be 12,x,12 because otherwise f_seek doesn't work
|
||||
last_drivenumber = drivenumber
|
||||
void c64.OPEN() ; open 12,8,12,"filename"
|
||||
if_cc {
|
||||
if c64.READST()==0 {
|
||||
iteration_in_progress = true
|
||||
have_first_byte = false
|
||||
void c64.CHKIN(11) ; use #11 as input channel
|
||||
void c64.CHKIN(12) ; use #12 as input channel
|
||||
if_cc {
|
||||
first_byte = c64.CHRIN() ; read first byte to test for file not found
|
||||
if not c64.READST() {
|
||||
@ -294,7 +296,7 @@ close_end:
|
||||
num_bytes--
|
||||
}
|
||||
|
||||
void c64.CHKIN(11) ; use #11 as input channel again
|
||||
void c64.CHKIN(12) ; use #12 as input channel again
|
||||
|
||||
%asm {{
|
||||
lda bufferpointer
|
||||
@ -359,8 +361,8 @@ m_in_buffer sta $ffff
|
||||
%asm {{
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldx #11
|
||||
jsr c64.CHKIN ; use channel 11 again for input
|
||||
ldx #12
|
||||
jsr c64.CHKIN ; use channel 12 again for input
|
||||
ldy #0
|
||||
lda have_first_byte
|
||||
beq _loop
|
||||
@ -389,23 +391,23 @@ _end rts
|
||||
; -- end an iterative file loading session (close channels).
|
||||
if iteration_in_progress {
|
||||
c64.CLRCHN()
|
||||
c64.CLOSE(11)
|
||||
c64.CLOSE(12)
|
||||
iteration_in_progress = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
; ----- iterative file saver functions (uses io channel 14) -----
|
||||
; ----- iterative file writing functions (uses io channel 13) -----
|
||||
|
||||
sub f_open_w(ubyte drivenumber, uword filenameptr) -> bool {
|
||||
; -- open a file for iterative writing with f_write
|
||||
f_close_w()
|
||||
|
||||
c64.SETNAM(string.length(filenameptr), filenameptr)
|
||||
c64.SETLFS(14, drivenumber, 1)
|
||||
void c64.OPEN() ; open 14,8,1,"filename"
|
||||
c64.SETLFS(13, drivenumber, 1)
|
||||
void c64.OPEN() ; open 13,8,1,"filename"
|
||||
if_cc {
|
||||
void c64.CHKOUT(14) ; use #14 as output channel
|
||||
c64.CHKOUT(13) ; use #13 as output channel
|
||||
return not c64.READST()
|
||||
}
|
||||
f_close_w()
|
||||
@ -413,9 +415,9 @@ _end rts
|
||||
}
|
||||
|
||||
sub f_write(uword bufferpointer, uword num_bytes) -> bool {
|
||||
; -- write the given umber of bytes to the currently open file
|
||||
; -- write the given number of bytes to the currently open file
|
||||
if num_bytes!=0 {
|
||||
void c64.CHKOUT(14) ; use #14 as output channel again
|
||||
c64.CHKOUT(13) ; use #13 as output channel again
|
||||
repeat num_bytes {
|
||||
c64.CHROUT(@(bufferpointer))
|
||||
bufferpointer++
|
||||
@ -428,7 +430,7 @@ _end rts
|
||||
sub f_close_w() {
|
||||
; -- end an iterative file writing session (close channels).
|
||||
c64.CLRCHN()
|
||||
c64.CLOSE(14)
|
||||
c64.CLOSE(13)
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,6 +102,7 @@ class TestCompilerOnExamplesCx16: FunSpec({
|
||||
"cube3d",
|
||||
"datetime",
|
||||
"diskspeed",
|
||||
"fileseek",
|
||||
"highresbitmap",
|
||||
"kefrenbars",
|
||||
"keyboardhandler",
|
||||
|
@ -3,7 +3,11 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- get rid of diskio.have_first_byte. But detecting invalid filenames should still work.
|
||||
- diskio.f_read doesn't signal end of file condition if the requested number of bytes==1 ?
|
||||
- diskio.f_read doesn't work if used after seek with buffer too small?
|
||||
- ir/vm: check weird asm chunks appearing in block?
|
||||
- try to get the cx16 adpcm example to output audio
|
||||
- attempt to fix the expression codegen bug with reused temp vars (github #89)
|
||||
- AstIdentifiersChecker: can a subroutine really not have the same name as its enclosing block? 64tass problem?
|
||||
- 6502 codegen: make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``p8v_``? Or not worth it (most 3 letter opcodes as variables are nonsensical anyway)
|
||||
|
85
examples/cx16/fileseek.p8
Normal file
85
examples/cx16/fileseek.p8
Normal file
@ -0,0 +1,85 @@
|
||||
; this program shows the use of the f_seek function to seek to a position in an opened file.
|
||||
; (this only works on Commander X16 DOS. on sdcard, not on host filesystem.)
|
||||
|
||||
%import diskio
|
||||
%import cx16diskio
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
str FILENAME = "seektestfile.bin"
|
||||
|
||||
sub start() {
|
||||
txt.print("writing data file...\n")
|
||||
uword total=0
|
||||
diskio.delete(8, FILENAME)
|
||||
if diskio.f_open_w(8, FILENAME) {
|
||||
repeat 1000 {
|
||||
str text = "hello world."
|
||||
void diskio.f_write(text, string.length(text))
|
||||
total += string.length(text)
|
||||
}
|
||||
diskio.f_close_w()
|
||||
txt.print("written size=")
|
||||
txt.print_uw(total)
|
||||
txt.nl()
|
||||
} else {
|
||||
txt.print("error: ")
|
||||
txt.print(diskio.status(8))
|
||||
sys.exit(1)
|
||||
}
|
||||
|
||||
read_last_bytes()
|
||||
|
||||
; txt.print("\nseeking to 11992 and writing a few bytes...\n")
|
||||
; if diskio.f_open_w(8, FILENAME) {
|
||||
; cx16diskio.f_seek_w(0,0,msb(11992),lsb(11992))
|
||||
; txt.print(diskio.status(8))
|
||||
; txt.nl()
|
||||
; void diskio.f_write("123", 3)
|
||||
; diskio.f_close_w()
|
||||
; } else {
|
||||
; txt.print("error: ")
|
||||
; txt.print(diskio.status(8))
|
||||
; sys.exit(1)
|
||||
; }
|
||||
;
|
||||
; read_last_bytes()
|
||||
}
|
||||
|
||||
sub read_last_bytes() {
|
||||
; read the last 10 bytes of the 12000 bytes file
|
||||
ubyte[256] buffer
|
||||
uword total = 0
|
||||
uword size
|
||||
txt.print("\nseeking to 11990 and reading...\n")
|
||||
if diskio.f_open(8, FILENAME) {
|
||||
cx16diskio.f_seek(0, 11990)
|
||||
do {
|
||||
size = diskio.f_read(buffer, sizeof(buffer))
|
||||
total += size
|
||||
} until size==0
|
||||
diskio.f_close()
|
||||
txt.print("size read=")
|
||||
txt.print_uw(total)
|
||||
txt.nl()
|
||||
buffer[lsb(total)] = 0
|
||||
txt.print("buffer read=")
|
||||
ubyte idx
|
||||
for idx in 0 to lsb(total-1) {
|
||||
txt.print_ubhex(buffer[idx], false)
|
||||
txt.spc()
|
||||
}
|
||||
txt.spc()
|
||||
txt.chrout('{')
|
||||
txt.print(buffer)
|
||||
txt.chrout('}')
|
||||
txt.nl()
|
||||
} else {
|
||||
txt.print("error: ")
|
||||
txt.print(diskio.status(8))
|
||||
sys.exit(1)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user