mirror of
https://github.com/irmen/prog8.git
synced 2024-09-30 00:55:52 +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
|
return $2000 * (cx16.getrambank() - startbank) + endaddress - startaddress
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub vload(str name @R0, ubyte device @Y, ubyte bank @A, uword address @R1) -> ubyte @A {
|
asmsub vload(str name @R0, ubyte drivenumber @Y, ubyte bank @A, uword address @R1) -> ubyte @A {
|
||||||
; -- like the basic command VLOAD "filename",device,bank,address
|
; -- 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
|
; 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)
|
; the file has to have the usual 2 byte header (which will be skipped)
|
||||||
%asm {{
|
%asm {{
|
||||||
@ -77,8 +77,8 @@ internal_vload:
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub vload_raw(str name @R0, ubyte device @Y, ubyte bank @A, uword address @R1) -> ubyte @A {
|
asmsub vload_raw(str name @R0, ubyte drivenumber @Y, ubyte bank @A, uword address @R1) -> ubyte @A {
|
||||||
; -- like the basic command BVLOAD "filename",device,bank,address
|
; -- 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
|
; 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.
|
; the file is read fully including the first two bytes.
|
||||||
%asm {{
|
%asm {{
|
||||||
@ -104,7 +104,7 @@ internal_vload:
|
|||||||
num_bytes--
|
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
|
; commander X16 supports fast block-read via macptr() kernal call
|
||||||
uword size
|
uword size
|
||||||
@ -191,7 +191,7 @@ m_in_buffer sta $ffff
|
|||||||
diskio.list_filename[1] = 'd'
|
diskio.list_filename[1] = 'd'
|
||||||
diskio.list_filename[2] = ':'
|
diskio.list_filename[2] = ':'
|
||||||
void string.copy(path, &diskio.list_filename+3)
|
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) {
|
sub mkdir(ubyte drivenumber, str name) {
|
||||||
@ -200,7 +200,7 @@ m_in_buffer sta $ffff
|
|||||||
diskio.list_filename[1] = 'd'
|
diskio.list_filename[1] = 'd'
|
||||||
diskio.list_filename[2] = ':'
|
diskio.list_filename[2] = ':'
|
||||||
void string.copy(name, &diskio.list_filename+3)
|
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) {
|
sub rmdir(ubyte drivenumber, str name) {
|
||||||
@ -212,7 +212,7 @@ m_in_buffer sta $ffff
|
|||||||
diskio.list_filename[1] = 'd'
|
diskio.list_filename[1] = 'd'
|
||||||
diskio.list_filename[2] = ':'
|
diskio.list_filename[2] = ':'
|
||||||
void string.copy(name, &diskio.list_filename+3)
|
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) {
|
sub relabel(ubyte drivenumber, str name) {
|
||||||
@ -222,6 +222,33 @@ m_in_buffer sta $ffff
|
|||||||
diskio.list_filename[2] = 'h'
|
diskio.list_filename[2] = 'h'
|
||||||
diskio.list_filename[3] = ':'
|
diskio.list_filename[3] = ':'
|
||||||
void string.copy(name, &diskio.list_filename+4)
|
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.
|
; -- Prints the directory contents of disk drive 8-11 to the screen. Returns success.
|
||||||
|
|
||||||
c64.SETNAM(1, "$")
|
c64.SETNAM(1, "$")
|
||||||
c64.SETLFS(13, drivenumber, 0)
|
c64.SETLFS(12, drivenumber, 0)
|
||||||
ubyte status = 1
|
ubyte status = 1
|
||||||
void c64.OPEN() ; open 13,8,0,"$"
|
void c64.OPEN() ; open 12,8,0,"$"
|
||||||
if_cs
|
if_cs
|
||||||
goto io_error
|
goto io_error
|
||||||
void c64.CHKIN(13) ; use #13 as input channel
|
void c64.CHKIN(12) ; use #12 as input channel
|
||||||
if_cs
|
if_cs
|
||||||
goto io_error
|
goto io_error
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ diskio {
|
|||||||
|
|
||||||
io_error:
|
io_error:
|
||||||
c64.CLRCHN() ; restore default i/o devices
|
c64.CLRCHN() ; restore default i/o devices
|
||||||
c64.CLOSE(13)
|
c64.CLOSE(12)
|
||||||
|
|
||||||
if status and status & $40 == 0 { ; bit 6=end of file
|
if status and status & $40 == 0 { ; bit 6=end of file
|
||||||
txt.print("\ni/o error, status: ")
|
txt.print("\ni/o error, status: ")
|
||||||
@ -69,12 +69,12 @@ io_error:
|
|||||||
; -- Returns pointer to disk name string or 0 if failure.
|
; -- Returns pointer to disk name string or 0 if failure.
|
||||||
|
|
||||||
c64.SETNAM(1, "$")
|
c64.SETNAM(1, "$")
|
||||||
c64.SETLFS(13, drivenumber, 0)
|
c64.SETLFS(12, drivenumber, 0)
|
||||||
ubyte okay = false
|
ubyte okay = false
|
||||||
void c64.OPEN() ; open 13,8,0,"$"
|
void c64.OPEN() ; open 12,8,0,"$"
|
||||||
if_cs
|
if_cs
|
||||||
goto io_error
|
goto io_error
|
||||||
void c64.CHKIN(13) ; use #13 as input channel
|
void c64.CHKIN(12) ; use #12 as input channel
|
||||||
if_cs
|
if_cs
|
||||||
goto io_error
|
goto io_error
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ io_error:
|
|||||||
|
|
||||||
io_error:
|
io_error:
|
||||||
c64.CLRCHN() ; restore default i/o devices
|
c64.CLRCHN() ; restore default i/o devices
|
||||||
c64.CLOSE(13)
|
c64.CLOSE(12)
|
||||||
if okay
|
if okay
|
||||||
return &list_filename
|
return &list_filename
|
||||||
return 0
|
return 0
|
||||||
@ -109,6 +109,7 @@ io_error:
|
|||||||
bool iteration_in_progress = false
|
bool iteration_in_progress = false
|
||||||
ubyte @zp first_byte
|
ubyte @zp first_byte
|
||||||
bool have_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_filetype = "???" ; prg, seq, dir
|
||||||
str list_filename = "?" * 50
|
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 {
|
sub f_open(ubyte drivenumber, uword filenameptr) -> bool {
|
||||||
; -- open a file for iterative reading with f_read
|
; -- open a file for iterative reading with f_read
|
||||||
@ -257,13 +258,14 @@ close_end:
|
|||||||
f_close()
|
f_close()
|
||||||
|
|
||||||
c64.SETNAM(string.length(filenameptr), filenameptr)
|
c64.SETNAM(string.length(filenameptr), filenameptr)
|
||||||
c64.SETLFS(11, drivenumber, 0)
|
c64.SETLFS(12, drivenumber, 12) ; note: has to be 12,x,12 because otherwise f_seek doesn't work
|
||||||
void c64.OPEN() ; open 11,8,0,"filename"
|
last_drivenumber = drivenumber
|
||||||
|
void c64.OPEN() ; open 12,8,12,"filename"
|
||||||
if_cc {
|
if_cc {
|
||||||
if c64.READST()==0 {
|
if c64.READST()==0 {
|
||||||
iteration_in_progress = true
|
iteration_in_progress = true
|
||||||
have_first_byte = false
|
have_first_byte = false
|
||||||
void c64.CHKIN(11) ; use #11 as input channel
|
void c64.CHKIN(12) ; use #12 as input channel
|
||||||
if_cc {
|
if_cc {
|
||||||
first_byte = c64.CHRIN() ; read first byte to test for file not found
|
first_byte = c64.CHRIN() ; read first byte to test for file not found
|
||||||
if not c64.READST() {
|
if not c64.READST() {
|
||||||
@ -294,7 +296,7 @@ close_end:
|
|||||||
num_bytes--
|
num_bytes--
|
||||||
}
|
}
|
||||||
|
|
||||||
void c64.CHKIN(11) ; use #11 as input channel again
|
void c64.CHKIN(12) ; use #12 as input channel again
|
||||||
|
|
||||||
%asm {{
|
%asm {{
|
||||||
lda bufferpointer
|
lda bufferpointer
|
||||||
@ -359,8 +361,8 @@ m_in_buffer sta $ffff
|
|||||||
%asm {{
|
%asm {{
|
||||||
sta P8ZP_SCRATCH_W1
|
sta P8ZP_SCRATCH_W1
|
||||||
sty P8ZP_SCRATCH_W1+1
|
sty P8ZP_SCRATCH_W1+1
|
||||||
ldx #11
|
ldx #12
|
||||||
jsr c64.CHKIN ; use channel 11 again for input
|
jsr c64.CHKIN ; use channel 12 again for input
|
||||||
ldy #0
|
ldy #0
|
||||||
lda have_first_byte
|
lda have_first_byte
|
||||||
beq _loop
|
beq _loop
|
||||||
@ -389,23 +391,23 @@ _end rts
|
|||||||
; -- end an iterative file loading session (close channels).
|
; -- end an iterative file loading session (close channels).
|
||||||
if iteration_in_progress {
|
if iteration_in_progress {
|
||||||
c64.CLRCHN()
|
c64.CLRCHN()
|
||||||
c64.CLOSE(11)
|
c64.CLOSE(12)
|
||||||
iteration_in_progress = false
|
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 {
|
sub f_open_w(ubyte drivenumber, uword filenameptr) -> bool {
|
||||||
; -- open a file for iterative writing with f_write
|
; -- open a file for iterative writing with f_write
|
||||||
f_close_w()
|
f_close_w()
|
||||||
|
|
||||||
c64.SETNAM(string.length(filenameptr), filenameptr)
|
c64.SETNAM(string.length(filenameptr), filenameptr)
|
||||||
c64.SETLFS(14, drivenumber, 1)
|
c64.SETLFS(13, drivenumber, 1)
|
||||||
void c64.OPEN() ; open 14,8,1,"filename"
|
void c64.OPEN() ; open 13,8,1,"filename"
|
||||||
if_cc {
|
if_cc {
|
||||||
void c64.CHKOUT(14) ; use #14 as output channel
|
c64.CHKOUT(13) ; use #13 as output channel
|
||||||
return not c64.READST()
|
return not c64.READST()
|
||||||
}
|
}
|
||||||
f_close_w()
|
f_close_w()
|
||||||
@ -413,9 +415,9 @@ _end rts
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub f_write(uword bufferpointer, uword num_bytes) -> bool {
|
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 {
|
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 {
|
repeat num_bytes {
|
||||||
c64.CHROUT(@(bufferpointer))
|
c64.CHROUT(@(bufferpointer))
|
||||||
bufferpointer++
|
bufferpointer++
|
||||||
@ -428,7 +430,7 @@ _end rts
|
|||||||
sub f_close_w() {
|
sub f_close_w() {
|
||||||
; -- end an iterative file writing session (close channels).
|
; -- end an iterative file writing session (close channels).
|
||||||
c64.CLRCHN()
|
c64.CLRCHN()
|
||||||
c64.CLOSE(14)
|
c64.CLOSE(13)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,6 +102,7 @@ class TestCompilerOnExamplesCx16: FunSpec({
|
|||||||
"cube3d",
|
"cube3d",
|
||||||
"datetime",
|
"datetime",
|
||||||
"diskspeed",
|
"diskspeed",
|
||||||
|
"fileseek",
|
||||||
"highresbitmap",
|
"highresbitmap",
|
||||||
"kefrenbars",
|
"kefrenbars",
|
||||||
"keyboardhandler",
|
"keyboardhandler",
|
||||||
|
@ -3,7 +3,11 @@ TODO
|
|||||||
|
|
||||||
For next release
|
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?
|
- 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)
|
- 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?
|
- 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)
|
- 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…
Reference in New Issue
Block a user