fixed diskio.f_read() for small read sizes

This commit is contained in:
Irmen de Jong 2022-11-23 23:20:24 +01:00
parent d4a35ba6ff
commit 7b6c742178
4 changed files with 61 additions and 64 deletions

View File

@ -96,7 +96,6 @@ internal_vload:
return 0
diskio.list_blocks = 0 ; we reuse this variable for the total number of bytes read
void c64.CHKIN(12) ; use #12 as input channel again
; commander X16 supports fast block-read via macptr() kernal call
uword size
@ -126,29 +125,23 @@ byte_read_loop: ; fallback if macptr() isn't supported on the device
lda bufferpointer+1
sta m_in_buffer+2
}}
repeat num_bytes {
while num_bytes {
if c64.READST() {
diskio.f_close()
if c64.READST() & $40 ; eof?
return diskio.list_blocks ; number of bytes read
return 0 ; error.
}
%asm {{
jsr c64.CHRIN
sta cx16.r5L
m_in_buffer sta $ffff
inc m_in_buffer+1
bne +
inc m_in_buffer+2
+ inc diskio.list_blocks
bne +
inc diskio.list_blocks+1
+
}}
if cx16.r5L==$0d { ; chance on I/o error status?
cx16.r5L = c64.READST()
if cx16.r5L & $40 {
diskio.f_close() ; end of file, close it
diskio.list_blocks-- ; don't count that last CHRIN read
}
if cx16.r5L
return diskio.list_blocks ; number of bytes read
}
diskio.list_blocks++
num_bytes--
}
return diskio.list_blocks ; number of bytes read
}
@ -162,9 +155,9 @@ m_in_buffer sta $ffff
uword total_read = 0
while not c64.READST() {
uword size = cx16diskio.f_read(bufferpointer, 256)
total_read += size
bufferpointer += size
cx16.r0 = cx16diskio.f_read(bufferpointer, 256)
total_read += cx16.r0
bufferpointer += cx16.r0
}
return total_read
}
@ -228,11 +221,11 @@ m_in_buffer sta $ffff
; 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
; cx16diskio.f_seek.command[1] = 13 ; f_open_w uses channel 13
; cx16diskio.f_seek.command[2] = lsb(pos_loword)
; cx16diskio.f_seek.command[3] = msb(pos_loword)
; cx16diskio.f_seek.command[4] = lsb(pos_hiword)
; cx16diskio.f_seek.command[5] = msb(pos_hiword)
; goto cx16diskio.f_seek.send_command
; }
}

View File

@ -287,7 +287,6 @@ close_end:
return 0
list_blocks = 0 ; we reuse this variable for the total number of bytes read
void c64.CHKIN(12) ; use #12 as input channel again
%asm {{
lda bufferpointer
@ -295,29 +294,23 @@ close_end:
lda bufferpointer+1
sta m_in_buffer+2
}}
repeat num_bytes {
while num_bytes {
if c64.READST() {
f_close()
if c64.READST() & $40 ; eof?
return list_blocks ; number of bytes read
return 0 ; error.
}
%asm {{
jsr c64.CHRIN
sta cx16.r5L
m_in_buffer sta $ffff
inc m_in_buffer+1
bne +
inc m_in_buffer+2
+ inc list_blocks
bne +
inc list_blocks+1
+
}}
if cx16.r5L==$0d { ; chance on I/o error status?
cx16.r5L = c64.READST()
if cx16.r5L & $40 {
f_close() ; end of file, close it
list_blocks-- ; don't count that last CHRIN read
}
if cx16.r5L
return list_blocks ; number of bytes read
}
list_blocks++
num_bytes--
}
return list_blocks ; number of bytes read
}
@ -329,9 +322,9 @@ m_in_buffer sta $ffff
uword total_read = 0
while not c64.READST() {
uword size = f_read(bufferpointer, 256)
total_read += size
bufferpointer += size
cx16.r0 = f_read(bufferpointer, 256)
total_read += cx16.r0
bufferpointer += cx16.r0
}
return total_read
}

View File

@ -3,10 +3,10 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- 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
- duplicate diskio for cx16 (get rid of cx16diskio, just copy diskio and tweak everything)
- get f_seek_w working like in the BASIC program - this needs the changes to diskio.f_open to use suffixes ,p,m
- 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)

View File

@ -8,15 +8,15 @@
%option no_sysinit
main {
str FILENAME = "seektestfile.bin"
uword megabuffer = memory("megabuffer", 20000, 256)
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."
if diskio.f_open_w(8, "@:seektestfile.bin,p,m") {
repeat 100 {
str text = "hello world.\n"
void diskio.f_write(text, string.length(text))
total += string.length(text)
}
@ -32,11 +32,9 @@ main {
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()
; txt.print("\nseeking to 1292 and writing a few bytes...\n")
; if diskio.f_open_w(8, "seektestfile.bin,p,m") {
; cx16diskio.f_seek_w(0, 1292)
; void diskio.f_write("123", 3)
; diskio.f_close_w()
; } else {
@ -49,31 +47,44 @@ main {
}
sub read_last_bytes() {
; read the last 10 bytes of the 12000 bytes file
ubyte[256] buffer
; read the last 10 bytes of the 1300 bytes file
uword total = 0
uword size
txt.print("\nseeking to 11990 and reading...\n")
if diskio.f_open(8, FILENAME) {
cx16diskio.f_seek(0, 11990)
txt.print("\nreading...\n")
if diskio.f_open(8, "seektestfile.bin,p,r") {
size = diskio.f_read_all(megabuffer)
diskio.f_close()
txt.print("size read:")
txt.print_uw(size)
txt.nl()
} else {
txt.print("error!\n")
sys.exit(1)
}
txt.print("\nseeking to 1290 and reading...\n")
if diskio.f_open(8, "seektestfile.bin,p,r") {
cx16diskio.f_seek(0, 1290)
uword ptr = megabuffer
do {
size = diskio.f_read(buffer, sizeof(buffer))
size = diskio.f_read(ptr, 255)
total += size
ptr += size
} until size==0
diskio.f_close()
txt.print("size read=")
txt.print_uw(total)
txt.nl()
buffer[lsb(total)] = 0
megabuffer[lsb(total)] = 0
txt.print("buffer read=")
ubyte idx
for idx in 0 to lsb(total-1) {
txt.print_ubhex(buffer[idx], false)
txt.print_ubhex(megabuffer[idx], false)
txt.spc()
}
txt.spc()
txt.chrout('{')
txt.print(buffer)
txt.print(megabuffer)
txt.chrout('}')
txt.nl()
} else {