mirror of
https://github.com/irmen/prog8.git
synced 2024-10-01 07:55:51 +00:00
cleaning up the diskio modules
for cx16: removed cx16diskio (merged everything into its regular diskio module) for cx16: the load() and load_raw() routines that took an extra ram bank parameter are gone. You have to cx16.rambank() yourself before calling load().
This commit is contained in:
parent
24aac7cee5
commit
180dbbb521
@ -1,239 +0,0 @@
|
|||||||
; Cx16 specific disk drive I/O routines.
|
|
||||||
|
|
||||||
%import diskio
|
|
||||||
%import string
|
|
||||||
|
|
||||||
cx16diskio {
|
|
||||||
|
|
||||||
; Same as diskio.load() but with additional bank parameter to select the Ram bank to load into.
|
|
||||||
; Use kernal LOAD routine to load the given program file in memory.
|
|
||||||
; This is similar to Basic's LOAD "filename",drive / LOAD "filename",drive,1
|
|
||||||
; If you don't give an address_override, the location in memory is taken from the 2-byte file header.
|
|
||||||
; If you specify a custom address_override, the first 2 bytes in the file are ignored
|
|
||||||
; and the rest is loaded at the given location in memory.
|
|
||||||
; Returns the end load address+1 if successful or 0 if a load error occurred.
|
|
||||||
; You can use the load_size() function to calcuate the size of the file that was loaded.
|
|
||||||
; TODO remove this, but add comment about bank and load_size to diskio.load_raw()
|
|
||||||
sub load(uword filenameptr, ubyte bank, uword address_override) -> uword {
|
|
||||||
cx16.rambank(bank)
|
|
||||||
return diskio.internal_load_routine(filenameptr, address_override, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
; Same as diskio.load_raw() but with additional bank parameter to select the Ram bank to load into.
|
|
||||||
; Use kernal LOAD routine to load the given file in memory.
|
|
||||||
; INCLUDING the first 2 bytes in the file: no program header is assumed in the file.
|
|
||||||
; The load address is mandatory. Returns the number of bytes loaded.
|
|
||||||
; If you load into regular system ram, use cx16.getrambank() for the bank argument,
|
|
||||||
; or alternatively make sure to reset the correct ram bank yourself after the load!
|
|
||||||
; Returns the end load address+1 if successful or 0 if a load error occurred.
|
|
||||||
; You can use the load_size() function to calcuate the size of the file that was loaded.
|
|
||||||
; TODO remove this, but add comment about bank and load_size to diskio.load_raw()
|
|
||||||
sub load_raw(uword filenameptr, ubyte bank, uword address_override) -> uword {
|
|
||||||
cx16.rambank(bank)
|
|
||||||
return diskio.internal_load_routine(filenameptr, address_override, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
; Replacement function that makes use of fast block read capability of the X16,
|
|
||||||
; and can wrap over multiple ram banks while reading.
|
|
||||||
; Use this in place of regular diskio.f_read() on X16.
|
|
||||||
; TODO use this one, get rid of diskio.f_read
|
|
||||||
sub f_read(uword bufferpointer, uword num_bytes) -> uword {
|
|
||||||
; -- read from the currently open file, up to the given number of bytes.
|
|
||||||
; returns the actual number of bytes read. (checks for End-of-file and error conditions)
|
|
||||||
if not diskio.iteration_in_progress or not num_bytes
|
|
||||||
return 0
|
|
||||||
|
|
||||||
diskio.list_blocks = 0 ; we reuse this variable for the total number of bytes read
|
|
||||||
|
|
||||||
; commander X16 supports fast block-read via macptr() kernal call
|
|
||||||
uword size
|
|
||||||
while num_bytes {
|
|
||||||
size = 255
|
|
||||||
if num_bytes<size
|
|
||||||
size = num_bytes
|
|
||||||
size = cx16.macptr(lsb(size), bufferpointer, false)
|
|
||||||
if_cs
|
|
||||||
goto byte_read_loop ; macptr block read not supported, do fallback loop
|
|
||||||
diskio.list_blocks += size
|
|
||||||
bufferpointer += size
|
|
||||||
if msb(bufferpointer) == $c0
|
|
||||||
bufferpointer = mkword($a0, lsb(bufferpointer)) ; wrap over bank boundary
|
|
||||||
num_bytes -= size
|
|
||||||
if cbm.READST() & $40 {
|
|
||||||
diskio.f_close() ; end of file, close it
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return diskio.list_blocks ; number of bytes read
|
|
||||||
|
|
||||||
byte_read_loop: ; fallback if macptr() isn't supported on the device
|
|
||||||
%asm {{
|
|
||||||
lda bufferpointer
|
|
||||||
sta m_in_buffer+1
|
|
||||||
lda bufferpointer+1
|
|
||||||
sta m_in_buffer+2
|
|
||||||
}}
|
|
||||||
while num_bytes {
|
|
||||||
if cbm.READST() {
|
|
||||||
diskio.f_close()
|
|
||||||
if cbm.READST() & $40 ; eof?
|
|
||||||
return diskio.list_blocks ; number of bytes read
|
|
||||||
return 0 ; error.
|
|
||||||
}
|
|
||||||
%asm {{
|
|
||||||
jsr cbm.CHRIN
|
|
||||||
m_in_buffer sta $ffff
|
|
||||||
inc m_in_buffer+1
|
|
||||||
bne +
|
|
||||||
inc m_in_buffer+2
|
|
||||||
+
|
|
||||||
}}
|
|
||||||
diskio.list_blocks++
|
|
||||||
num_bytes--
|
|
||||||
}
|
|
||||||
return diskio.list_blocks ; number of bytes read
|
|
||||||
}
|
|
||||||
|
|
||||||
; replacement function that makes use of fast block read capability of the X16
|
|
||||||
; use this in place of regular diskio.f_read_all() on X16
|
|
||||||
; TODO use this one, get rid of diskio.f_read
|
|
||||||
sub f_read_all(uword bufferpointer) -> uword {
|
|
||||||
; -- read the full contents of the file, returns number of bytes read.
|
|
||||||
if not diskio.iteration_in_progress
|
|
||||||
return 0
|
|
||||||
|
|
||||||
uword total_read = 0
|
|
||||||
while not cbm.READST() {
|
|
||||||
cx16.r0 = cx16diskio.f_read(bufferpointer, 256)
|
|
||||||
total_read += cx16.r0
|
|
||||||
bufferpointer += cx16.r0
|
|
||||||
}
|
|
||||||
return total_read
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
; CommanderX16 extensions over the basic C64/C128 diskio routines:
|
|
||||||
|
|
||||||
; For use directly after a load or load_raw call (don't mess with the ram bank yet):
|
|
||||||
; Calculates the number of bytes loaded (files > 64Kb ar truncated to 16 bits)
|
|
||||||
sub load_size(ubyte startbank, uword startaddress, uword endaddress) -> uword {
|
|
||||||
return $2000 * (cx16.getrambank() - startbank) + endaddress - startaddress
|
|
||||||
}
|
|
||||||
|
|
||||||
asmsub vload(str name @R0, 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 {{
|
|
||||||
clc
|
|
||||||
internal_vload:
|
|
||||||
phx
|
|
||||||
pha
|
|
||||||
ldx diskio.drivenumber
|
|
||||||
bcc +
|
|
||||||
ldy #%00000010 ; headerless load mode
|
|
||||||
bne ++
|
|
||||||
+ ldy #0 ; normal load mode
|
|
||||||
+ lda #1
|
|
||||||
jsr cbm.SETLFS
|
|
||||||
lda cx16.r0
|
|
||||||
ldy cx16.r0+1
|
|
||||||
jsr prog8_lib.strlen
|
|
||||||
tya
|
|
||||||
ldx cx16.r0
|
|
||||||
ldy cx16.r0+1
|
|
||||||
jsr cbm.SETNAM
|
|
||||||
pla
|
|
||||||
clc
|
|
||||||
adc #2
|
|
||||||
ldx cx16.r1
|
|
||||||
ldy cx16.r1+1
|
|
||||||
stz P8ZP_SCRATCH_B1
|
|
||||||
jsr cbm.LOAD
|
|
||||||
bcs +
|
|
||||||
inc P8ZP_SCRATCH_B1
|
|
||||||
+ jsr cbm.CLRCHN
|
|
||||||
lda #1
|
|
||||||
jsr cbm.CLOSE
|
|
||||||
plx
|
|
||||||
lda P8ZP_SCRATCH_B1
|
|
||||||
rts
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
asmsub vload_raw(str name @R0, 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 {{
|
|
||||||
sec
|
|
||||||
jmp vload.internal_vload
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
sub chdir(str path) {
|
|
||||||
; -- change current directory.
|
|
||||||
diskio.list_filename[0] = 'c'
|
|
||||||
diskio.list_filename[1] = 'd'
|
|
||||||
diskio.list_filename[2] = ':'
|
|
||||||
void string.copy(path, &diskio.list_filename+3)
|
|
||||||
diskio.send_command(diskio.list_filename)
|
|
||||||
}
|
|
||||||
|
|
||||||
sub mkdir(str name) {
|
|
||||||
; -- make a new subdirectory.
|
|
||||||
diskio.list_filename[0] = 'm'
|
|
||||||
diskio.list_filename[1] = 'd'
|
|
||||||
diskio.list_filename[2] = ':'
|
|
||||||
void string.copy(name, &diskio.list_filename+3)
|
|
||||||
diskio.send_command(diskio.list_filename)
|
|
||||||
}
|
|
||||||
|
|
||||||
sub rmdir(str name) {
|
|
||||||
; -- remove a subdirectory.
|
|
||||||
void string.find(name, '*')
|
|
||||||
if_cs
|
|
||||||
return ; refuse to act on a wildcard *
|
|
||||||
diskio.list_filename[0] = 'r'
|
|
||||||
diskio.list_filename[1] = 'd'
|
|
||||||
diskio.list_filename[2] = ':'
|
|
||||||
void string.copy(name, &diskio.list_filename+3)
|
|
||||||
diskio.send_command(diskio.list_filename)
|
|
||||||
}
|
|
||||||
|
|
||||||
sub relabel(str name) {
|
|
||||||
; -- change the disk label.
|
|
||||||
diskio.list_filename[0] = 'r'
|
|
||||||
diskio.list_filename[1] = '-'
|
|
||||||
diskio.list_filename[2] = 'h'
|
|
||||||
diskio.list_filename[3] = ':'
|
|
||||||
void string.copy(name, &diskio.list_filename+4)
|
|
||||||
diskio.send_command(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:
|
|
||||||
cbm.SETNAM(sizeof(command), &command)
|
|
||||||
cbm.SETLFS(15, diskio.drivenumber, 15)
|
|
||||||
void cbm.OPEN()
|
|
||||||
cbm.CLOSE(15)
|
|
||||||
}
|
|
||||||
|
|
||||||
; 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] = 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
|
|
||||||
; }
|
|
||||||
}
|
|
@ -129,7 +129,7 @@ io_error:
|
|||||||
if lf_start_list(pattern_ptr) {
|
if lf_start_list(pattern_ptr) {
|
||||||
while lf_next_entry() {
|
while lf_next_entry() {
|
||||||
if list_filetype!="dir" {
|
if list_filetype!="dir" {
|
||||||
filenames_buffer += string.copy(diskio.list_filename, filenames_buffer) + 1
|
filenames_buffer += string.copy(list_filename, filenames_buffer) + 1
|
||||||
files_found++
|
files_found++
|
||||||
if filenames_buffer - buffer_start > filenames_buf_size-20 {
|
if filenames_buffer - buffer_start > filenames_buf_size-20 {
|
||||||
@(filenames_buffer)=0
|
@(filenames_buffer)=0
|
||||||
@ -282,18 +282,37 @@ close_end:
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; optimized for Commander X16 to use MACPTR block read kernal call
|
||||||
sub f_read(uword bufferpointer, uword num_bytes) -> uword {
|
sub f_read(uword bufferpointer, uword num_bytes) -> uword {
|
||||||
; -- read from the currently open file, up to the given number of bytes.
|
; -- read from the currently open file, up to the given number of bytes.
|
||||||
; returns the actual number of bytes read. (checks for End-of-file and error conditions)
|
; returns the actual number of bytes read. (checks for End-of-file and error conditions)
|
||||||
; NOTE: on systems with banked ram (such as Commander X16) this routine DOES NOT
|
|
||||||
; automatically load into subsequent banks if it reaches a bank boundary!
|
|
||||||
; Consider using cx16diskio.f_read() on X16.
|
|
||||||
; TODO join modules
|
|
||||||
if not iteration_in_progress or not num_bytes
|
if not iteration_in_progress or not num_bytes
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
list_blocks = 0 ; we reuse this variable for the total number of bytes read
|
list_blocks = 0 ; we reuse this variable for the total number of bytes read
|
||||||
|
|
||||||
|
; commander X16 supports fast block-read via macptr() kernal call
|
||||||
|
uword size
|
||||||
|
while num_bytes {
|
||||||
|
size = 255
|
||||||
|
if num_bytes<size
|
||||||
|
size = num_bytes
|
||||||
|
size = cx16.macptr(lsb(size), bufferpointer, false)
|
||||||
|
if_cs
|
||||||
|
goto byte_read_loop ; macptr block read not supported, do fallback loop
|
||||||
|
list_blocks += size
|
||||||
|
bufferpointer += size
|
||||||
|
if msb(bufferpointer) == $c0
|
||||||
|
bufferpointer = mkword($a0, lsb(bufferpointer)) ; wrap over bank boundary
|
||||||
|
num_bytes -= size
|
||||||
|
if cbm.READST() & $40 {
|
||||||
|
f_close() ; end of file, close it
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list_blocks ; number of bytes read
|
||||||
|
|
||||||
|
byte_read_loop: ; fallback if macptr() isn't supported on the device
|
||||||
%asm {{
|
%asm {{
|
||||||
lda bufferpointer
|
lda bufferpointer
|
||||||
sta m_in_buffer+1
|
sta m_in_buffer+1
|
||||||
@ -321,9 +340,9 @@ m_in_buffer sta $ffff
|
|||||||
return list_blocks ; number of bytes read
|
return list_blocks ; number of bytes read
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; optimized for Commander X16 to use MACPTR block read kernal call
|
||||||
sub f_read_all(uword bufferpointer) -> uword {
|
sub f_read_all(uword bufferpointer) -> uword {
|
||||||
; -- read the full contents of the file, returns number of bytes read.
|
; -- read the full contents of the file, returns number of bytes read.
|
||||||
; Note: Consider using cx16diskio.f_read_all() on X16! TODO join modules
|
|
||||||
if not iteration_in_progress
|
if not iteration_in_progress
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@ -482,20 +501,17 @@ io_error:
|
|||||||
; NOTE: when the load is larger than 64Kb and/or spans multiple RAM banks
|
; NOTE: when the load is larger than 64Kb and/or spans multiple RAM banks
|
||||||
; (which is possible on the Commander X16), the returned size is not correct,
|
; (which is possible on the Commander X16), the returned size is not correct,
|
||||||
; because it doesn't take the number of ram banks into account.
|
; because it doesn't take the number of ram banks into account.
|
||||||
; Also consider using cx16diskio.load() instead on the Commander X16. TODO join modules
|
; You can use the load_size() function to calcuate the size in this case.
|
||||||
|
; NOTE: data is read into the current Ram bank if you're reading into banked ram.
|
||||||
|
; if you require loading into another ram bank, you have to set that
|
||||||
|
; yourself using cx16.rambank(bank) before calling load().
|
||||||
sub load(uword filenameptr, uword address_override) -> uword {
|
sub load(uword filenameptr, uword address_override) -> uword {
|
||||||
return internal_load_routine(filenameptr, address_override, false)
|
return internal_load_routine(filenameptr, address_override, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
; Use kernal LOAD routine to load the given file in memory.
|
; Identical to load(), but DOES INCLUDE the first 2 bytes in the file.
|
||||||
; INCLUDING the first 2 bytes in the file: no program header is assumed in the file.
|
; No program header is assumed in the file. Everything is loaded.
|
||||||
; This is different from Basic's LOAD instruction which always skips the first two bytes.
|
; See comments on load() for more details.
|
||||||
; The load address is mandatory.
|
|
||||||
; Returns the end load address+1 if successful or 0 if a load error occurred.
|
|
||||||
; NOTE: when the load is larger than 64Kb and/or spans multiple RAM banks
|
|
||||||
; (which is possible on the Commander X16), the returned size is not correct,
|
|
||||||
; because it doesn't take the number of ram banks into account.
|
|
||||||
; Also consider using cx16diskio.load_raw() instead on the Commander X16. TODO join modules
|
|
||||||
sub load_raw(uword filenameptr, uword address) -> uword {
|
sub load_raw(uword filenameptr, uword address) -> uword {
|
||||||
return internal_load_routine(filenameptr, address, true)
|
return internal_load_routine(filenameptr, address, true)
|
||||||
}
|
}
|
||||||
@ -561,4 +577,131 @@ io_error:
|
|||||||
cbm.CLRCHN()
|
cbm.CLRCHN()
|
||||||
cbm.CLOSE(15)
|
cbm.CLOSE(15)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
; CommanderX16 extensions over the basic C64/C128 diskio routines:
|
||||||
|
|
||||||
|
; For use directly after a load or load_raw call (don't mess with the ram bank yet):
|
||||||
|
; Calculates the number of bytes loaded (files > 64Kb ar truncated to 16 bits)
|
||||||
|
sub load_size(ubyte startbank, uword startaddress, uword endaddress) -> uword {
|
||||||
|
return $2000 * (cx16.getrambank() - startbank) + endaddress - startaddress
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub vload(str name @R0, 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 {{
|
||||||
|
clc
|
||||||
|
internal_vload:
|
||||||
|
phx
|
||||||
|
pha
|
||||||
|
ldx drivenumber
|
||||||
|
bcc +
|
||||||
|
ldy #%00000010 ; headerless load mode
|
||||||
|
bne ++
|
||||||
|
+ ldy #0 ; normal load mode
|
||||||
|
+ lda #1
|
||||||
|
jsr cbm.SETLFS
|
||||||
|
lda cx16.r0
|
||||||
|
ldy cx16.r0+1
|
||||||
|
jsr prog8_lib.strlen
|
||||||
|
tya
|
||||||
|
ldx cx16.r0
|
||||||
|
ldy cx16.r0+1
|
||||||
|
jsr cbm.SETNAM
|
||||||
|
pla
|
||||||
|
clc
|
||||||
|
adc #2
|
||||||
|
ldx cx16.r1
|
||||||
|
ldy cx16.r1+1
|
||||||
|
stz P8ZP_SCRATCH_B1
|
||||||
|
jsr cbm.LOAD
|
||||||
|
bcs +
|
||||||
|
inc P8ZP_SCRATCH_B1
|
||||||
|
+ jsr cbm.CLRCHN
|
||||||
|
lda #1
|
||||||
|
jsr cbm.CLOSE
|
||||||
|
plx
|
||||||
|
lda P8ZP_SCRATCH_B1
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub vload_raw(str name @R0, 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 {{
|
||||||
|
sec
|
||||||
|
jmp vload.internal_vload
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub chdir(str path) {
|
||||||
|
; -- change current directory.
|
||||||
|
list_filename[0] = 'c'
|
||||||
|
list_filename[1] = 'd'
|
||||||
|
list_filename[2] = ':'
|
||||||
|
void string.copy(path, &list_filename+3)
|
||||||
|
send_command(list_filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
sub mkdir(str name) {
|
||||||
|
; -- make a new subdirectory.
|
||||||
|
list_filename[0] = 'm'
|
||||||
|
list_filename[1] = 'd'
|
||||||
|
list_filename[2] = ':'
|
||||||
|
void string.copy(name, &list_filename+3)
|
||||||
|
send_command(list_filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
sub rmdir(str name) {
|
||||||
|
; -- remove a subdirectory.
|
||||||
|
void string.find(name, '*')
|
||||||
|
if_cs
|
||||||
|
return ; refuse to act on a wildcard *
|
||||||
|
list_filename[0] = 'r'
|
||||||
|
list_filename[1] = 'd'
|
||||||
|
list_filename[2] = ':'
|
||||||
|
void string.copy(name, &list_filename+3)
|
||||||
|
send_command(list_filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
sub relabel(str name) {
|
||||||
|
; -- change the disk label.
|
||||||
|
list_filename[0] = 'r'
|
||||||
|
list_filename[1] = '-'
|
||||||
|
list_filename[2] = 'h'
|
||||||
|
list_filename[3] = ':'
|
||||||
|
void string.copy(name, &list_filename+4)
|
||||||
|
send_command(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:
|
||||||
|
cbm.SETNAM(sizeof(command), &command)
|
||||||
|
cbm.SETLFS(15, drivenumber, 15)
|
||||||
|
void cbm.OPEN()
|
||||||
|
cbm.CLOSE(15)
|
||||||
|
}
|
||||||
|
|
||||||
|
; 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
|
||||||
|
; f_seek.command[1] = 13 ; f_open_w uses channel 13
|
||||||
|
; f_seek.command[2] = lsb(pos_loword)
|
||||||
|
; f_seek.command[3] = msb(pos_loword)
|
||||||
|
; f_seek.command[4] = lsb(pos_hiword)
|
||||||
|
; f_seek.command[5] = msb(pos_hiword)
|
||||||
|
; goto f_seek.send_command
|
||||||
|
; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ io_error:
|
|||||||
if lf_start_list(pattern_ptr) {
|
if lf_start_list(pattern_ptr) {
|
||||||
while lf_next_entry() {
|
while lf_next_entry() {
|
||||||
if list_filetype!="dir" {
|
if list_filetype!="dir" {
|
||||||
filenames_buffer += string.copy(diskio.list_filename, filenames_buffer) + 1
|
filenames_buffer += string.copy(list_filename, filenames_buffer) + 1
|
||||||
files_found++
|
files_found++
|
||||||
if filenames_buffer - buffer_start > filenames_buf_size-20 {
|
if filenames_buffer - buffer_start > filenames_buf_size-20 {
|
||||||
@(filenames_buffer)=0
|
@(filenames_buffer)=0
|
||||||
@ -497,11 +497,9 @@ io_error:
|
|||||||
return cx16.r1
|
return cx16.r1
|
||||||
}
|
}
|
||||||
|
|
||||||
; Use kernal LOAD routine to load the given file in memory.
|
; Identical to load(), but DOES INCLUDE the first 2 bytes in the file.
|
||||||
; INCLUDING the first 2 bytes in the file: no program header is assumed in the file.
|
; No program header is assumed in the file. Everything is loaded.
|
||||||
; This is different from Basic's LOAD instruction which always skips the first two bytes.
|
; See comments on load() for more details.
|
||||||
; The load address is mandatory.
|
|
||||||
; Returns the end load address+1 if successful or 0 if a load error occurred.
|
|
||||||
sub load_raw(uword filenameptr, uword address) -> uword {
|
sub load_raw(uword filenameptr, uword address) -> uword {
|
||||||
; read the 2 header bytes separately to skip them
|
; read the 2 header bytes separately to skip them
|
||||||
if not f_open(filenameptr)
|
if not f_open(filenameptr)
|
||||||
|
@ -150,7 +150,12 @@ Provides several routines that deal with disk drive I/O, such as:
|
|||||||
- delete and rename files on the disk
|
- delete and rename files on the disk
|
||||||
- send arbitrary CbmDos command to disk drive
|
- send arbitrary CbmDos command to disk drive
|
||||||
|
|
||||||
|
Commander X16 additions:
|
||||||
On the Commander X16 it tries to use that machine's fast Kernal loading routines if possible.
|
On the Commander X16 it tries to use that machine's fast Kernal loading routines if possible.
|
||||||
|
Routines to directly load data into video ram are also present (vload and vload_raw).
|
||||||
|
Also contains a helper function to calculate the file size of a loaded file (although that is truncated
|
||||||
|
to 16 bits, 64Kb)
|
||||||
|
Als contains routines for operating on subdirectories (chdir, mkdir, rmdir) and to relabel the disk.
|
||||||
|
|
||||||
|
|
||||||
string
|
string
|
||||||
@ -381,16 +386,6 @@ because the Commander X16's default colors for this (the first 16 colors) are to
|
|||||||
and are quite different than how they looked on a VIC-II chip in a C64.
|
and are quite different than how they looked on a VIC-II chip in a C64.
|
||||||
|
|
||||||
|
|
||||||
cx16diskio (cx16 only)
|
|
||||||
-----------------------
|
|
||||||
Available for the Cx16 target. Contains extensions to the load and load_raw routines from the regular
|
|
||||||
diskio module, to deal with loading of potentially large files in to banked ram (HiRam).
|
|
||||||
Routines to directly load data into video ram are also present (vload and vload_raw).
|
|
||||||
Also contains a helper function to calculate the file size of a loaded file (although that is truncated
|
|
||||||
to 16 bits, 64Kb)
|
|
||||||
Als contains routines for operating on subdirectories (chdir, mkdir, rmdir) and to relabel the disk.
|
|
||||||
|
|
||||||
|
|
||||||
psg (cx16 only)
|
psg (cx16 only)
|
||||||
----------------
|
----------------
|
||||||
Available for the Cx16 target.
|
Available for the Cx16 target.
|
||||||
|
@ -8,14 +8,14 @@ For 9.0 major changes
|
|||||||
- DONE: rename sqrt16() to just sqrt(), make it accept multiple numeric types. Renamed floats.sqrt() to floats.sqrtf() but you can just use sqrt()
|
- DONE: rename sqrt16() to just sqrt(), make it accept multiple numeric types. Renamed floats.sqrt() to floats.sqrtf() but you can just use sqrt()
|
||||||
- DONE: abs() now supports multiple datatypes including float. No need to use floats.fabs() anymore.
|
- DONE: abs() now supports multiple datatypes including float. No need to use floats.fabs() anymore.
|
||||||
- DONE: divmod() now supports multiple datatypes. divmodw() has been removed.
|
- DONE: divmod() now supports multiple datatypes. divmodw() has been removed.
|
||||||
- DONE: drivenumber parameter removed from all routines in diskio and cx16diskio modules. The drive to work on is now simply stored as a diskio.drivenumber variable, which defaults to 8.
|
- DONE: cx16diskio module merged into diskio (which got specialized for commander x16 target). load() and load_raw() with extra ram bank parameter are gone.
|
||||||
|
- DONE: drivenumber parameter removed from all routines in diskio module. The drive to work on is now simply stored as a diskio.drivenumber variable, which defaults to 8.
|
||||||
|
|
||||||
- duplicate diskio for cx16 (get rid of cx16diskio, just copy diskio and tweak everything) + documentation
|
- get f_seek_w working like in the BASIC program on the sdcard - this needs the changes to diskio.f_open to use suffixes ,p,m
|
||||||
- 6502 codegen: see if we can let for loops skip the loop if startvar>endvar, without adding a lot of code size/duplicating the loop condition.
|
- 6502 codegen: see if we can let for loops skip the loop if startvar>endvar, without adding a lot of code size/duplicating the loop condition.
|
||||||
It is documented behavior to now loop 'around' $00 but it's too easy to forget about!
|
It is documented behavior to now loop 'around' $00 but it's too easy to forget about!
|
||||||
Lot of work because of so many special cases in ForLoopsAsmgen.....
|
Lot of work because of so many special cases in ForLoopsAsmgen.....
|
||||||
(vm codegen already behaves like this!)
|
(vm codegen already behaves like this!)
|
||||||
- get f_seek_w working like in the BASIC program - this needs the changes to diskio.f_open to use suffixes ,p,m
|
|
||||||
- once 9.0 is stable, upgrade other programs (assem, shell, etc) to it. + add migration guide to the manual.
|
- once 9.0 is stable, upgrade other programs (assem, shell, etc) to it. + add migration guide to the manual.
|
||||||
- [much work:] add special (u)word array type (or modifier such as @fast? ) that puts the array into memory as 2 separate byte-arrays 1 for LSB 1 for MSB -> allows for word arrays of length 256 and faster indexing
|
- [much work:] add special (u)word array type (or modifier such as @fast? ) that puts the array into memory as 2 separate byte-arrays 1 for LSB 1 for MSB -> allows for word arrays of length 256 and faster indexing
|
||||||
this is an enormous amout of work, if this type is to be treated equally as existing (u)word , because all expression / lookup / assignment routines need to know about the distinction....
|
this is an enormous amout of work, if this type is to be treated equally as existing (u)word , because all expression / lookup / assignment routines need to know about the distinction....
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
%import diskio
|
%import diskio
|
||||||
%import cx16diskio
|
|
||||||
%import floats
|
%import floats
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
@ -59,7 +58,8 @@ main {
|
|||||||
batchtotaltime = 0
|
batchtotaltime = 0
|
||||||
repeat REPEATS {
|
repeat REPEATS {
|
||||||
cbm.SETTIM(0,0,0)
|
cbm.SETTIM(0,0,0)
|
||||||
if not cx16diskio.load("benchmark.dat", 4, $a000)
|
cx16.rambank(4)
|
||||||
|
if not diskio.load("benchmark.dat", $a000)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
batchtotaltime += cbm.RDTIM16()
|
batchtotaltime += cbm.RDTIM16()
|
||||||
txt.chrout('.')
|
txt.chrout('.')
|
||||||
@ -70,7 +70,7 @@ main {
|
|||||||
batchtotaltime = 0
|
batchtotaltime = 0
|
||||||
repeat REPEATS {
|
repeat REPEATS {
|
||||||
cbm.SETTIM(0,0,0)
|
cbm.SETTIM(0,0,0)
|
||||||
if not cx16diskio.vload("benchmark.dat", 0, $0000)
|
if not diskio.vload("benchmark.dat", 0, $0000)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
batchtotaltime += cbm.RDTIM16()
|
batchtotaltime += cbm.RDTIM16()
|
||||||
txt.chrout('.')
|
txt.chrout('.')
|
||||||
@ -99,7 +99,7 @@ main {
|
|||||||
if diskio.f_open("benchmark.dat") {
|
if diskio.f_open("benchmark.dat") {
|
||||||
cbm.SETTIM(0,0,0)
|
cbm.SETTIM(0,0,0)
|
||||||
repeat 65536/255 {
|
repeat 65536/255 {
|
||||||
if not cx16diskio.f_read(buffer, 255)
|
if not diskio.f_read(buffer, 255)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
}
|
}
|
||||||
batchtotaltime += cbm.RDTIM16()
|
batchtotaltime += cbm.RDTIM16()
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
; (this only works on Commander X16 DOS. on sdcard, not on host filesystem.)
|
; (this only works on Commander X16 DOS. on sdcard, not on host filesystem.)
|
||||||
|
|
||||||
%import diskio
|
%import diskio
|
||||||
%import cx16diskio
|
|
||||||
%import textio
|
%import textio
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
@ -35,7 +34,7 @@ main {
|
|||||||
; NOTE: f_seek_w() doesn't work right now. It requires substantial changes to the diskio library that are not compatible with the C64/C128.
|
; NOTE: f_seek_w() doesn't work right now. It requires substantial changes to the diskio library that are not compatible with the C64/C128.
|
||||||
; txt.print("\nseeking to 1292 and writing a few bytes...\n")
|
; txt.print("\nseeking to 1292 and writing a few bytes...\n")
|
||||||
; if diskio.f_open_w("seektestfile.bin,p,m") {
|
; if diskio.f_open_w("seektestfile.bin,p,m") {
|
||||||
; cx16diskio.f_seek_w(0, 1292)
|
; diskio.f_seek_w(0, 1292)
|
||||||
; void diskio.f_write("123", 3)
|
; void diskio.f_write("123", 3)
|
||||||
; diskio.f_close_w()
|
; diskio.f_close_w()
|
||||||
; } else {
|
; } else {
|
||||||
@ -65,7 +64,7 @@ main {
|
|||||||
|
|
||||||
txt.print("\nseeking to 1290 and reading...\n")
|
txt.print("\nseeking to 1290 and reading...\n")
|
||||||
if diskio.f_open("seektestfile.bin") {
|
if diskio.f_open("seektestfile.bin") {
|
||||||
cx16diskio.f_seek(0, 1290)
|
diskio.f_seek(0, 1290)
|
||||||
uword ptr = megabuffer
|
uword ptr = megabuffer
|
||||||
do {
|
do {
|
||||||
size = diskio.f_read(ptr, 255)
|
size = diskio.f_read(ptr, 255)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import diskio
|
%import diskio
|
||||||
%import cx16diskio
|
|
||||||
%import floats
|
%import floats
|
||||||
%import adpcm
|
%import adpcm
|
||||||
%import wavfile
|
%import wavfile
|
||||||
@ -41,7 +40,7 @@ main {
|
|||||||
txt.print(MUSIC_FILENAME)
|
txt.print(MUSIC_FILENAME)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
if diskio.f_open(MUSIC_FILENAME) {
|
if diskio.f_open(MUSIC_FILENAME) {
|
||||||
void cx16diskio.f_read(buffer, 128)
|
void diskio.f_read(buffer, 128)
|
||||||
wav_ok = wavfile.parse_header(buffer)
|
wav_ok = wavfile.parse_header(buffer)
|
||||||
diskio.f_close()
|
diskio.f_close()
|
||||||
}
|
}
|
||||||
@ -105,13 +104,13 @@ main {
|
|||||||
uword block_size = 1024
|
uword block_size = 1024
|
||||||
if wavfile.wavefmt==wavfile.WAVE_FORMAT_DVI_ADPCM
|
if wavfile.wavefmt==wavfile.WAVE_FORMAT_DVI_ADPCM
|
||||||
block_size = wavfile.block_align
|
block_size = wavfile.block_align
|
||||||
void cx16diskio.f_read(buffer, wavfile.data_offset) ; skip to actual sample data start
|
void diskio.f_read(buffer, wavfile.data_offset) ; skip to actual sample data start
|
||||||
void cx16diskio.f_read(buffer, block_size) ; preload buffer
|
void diskio.f_read(buffer, block_size) ; preload buffer
|
||||||
cx16.VERA_AUDIO_RATE = vera_rate ; start playback
|
cx16.VERA_AUDIO_RATE = vera_rate ; start playback
|
||||||
repeat {
|
repeat {
|
||||||
interrupt.wait_and_clear_aflow_semaphore()
|
interrupt.wait_and_clear_aflow_semaphore()
|
||||||
;; cx16.vpoke(1,$fa00, $a0) ; paint a screen color
|
;; cx16.vpoke(1,$fa00, $a0) ; paint a screen color
|
||||||
uword size = cx16diskio.f_read(buffer, block_size)
|
uword size = diskio.f_read(buffer, block_size)
|
||||||
;; cx16.vpoke(1,$fa00, $00) ; paint a screen color
|
;; cx16.vpoke(1,$fa00, $00) ; paint a screen color
|
||||||
if size<block_size
|
if size<block_size
|
||||||
break
|
break
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import cx16diskio
|
%import diskio
|
||||||
%import palette
|
%import palette
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%zpreserved $22,$2d ; zsound lib uses this region
|
%zpreserved $22,$2d ; zsound lib uses this region
|
||||||
@ -53,11 +53,13 @@ zsound_lib:
|
|||||||
txt.print("zsound demo program (drive 8)!\n")
|
txt.print("zsound demo program (drive 8)!\n")
|
||||||
|
|
||||||
cbm.SETMSG(%10000000) ; enable kernal status messages for load
|
cbm.SETMSG(%10000000) ; enable kernal status messages for load
|
||||||
if not cx16diskio.load_raw("colony.zsm", song_bank, song_address) {
|
cx16.rambank(song_bank)
|
||||||
|
if not diskio.load_raw("colony.zsm", song_address) {
|
||||||
txt.print("?can't load\n")
|
txt.print("?can't load\n")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if not cx16diskio.load_raw("terminator2.zcm", digi_bank, digi_address) {
|
cx16.rambank(digi_bank)
|
||||||
|
if not diskio.load_raw("terminator2.zcm", digi_address) {
|
||||||
txt.print("?can't load\n")
|
txt.print("?can't load\n")
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import diskio
|
%import diskio
|
||||||
%import cx16diskio
|
|
||||||
%zpreserved $22,$2d ; zsound lib uses this region
|
%zpreserved $22,$2d ; zsound lib uses this region
|
||||||
|
|
||||||
; NOTE: this is a proof of concept to stream ZCM digi from disk while playing.
|
; NOTE: this is a proof of concept to stream ZCM digi from disk while playing.
|
||||||
@ -44,7 +43,7 @@ zsound_lib:
|
|||||||
|
|
||||||
sub prebuffer() {
|
sub prebuffer() {
|
||||||
txt.print("prebuffering...")
|
txt.print("prebuffering...")
|
||||||
void cx16diskio.f_read(digi_address, ram_bank_size*4)
|
void diskio.f_read(digi_address, ram_bank_size*4)
|
||||||
}
|
}
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
@ -65,7 +64,7 @@ zsound_lib:
|
|||||||
txt.print("\nstreaming from file, playback in irq!\n")
|
txt.print("\nstreaming from file, playback in irq!\n")
|
||||||
uword size = 1
|
uword size = 1
|
||||||
while size {
|
while size {
|
||||||
size = cx16diskio.f_read(digi_address, ram_bank_size) ; load next bank
|
size = diskio.f_read(digi_address, ram_bank_size) ; load next bank
|
||||||
txt.print_ub(cx16.getrambank())
|
txt.print_ub(cx16.getrambank())
|
||||||
txt.spc()
|
txt.spc()
|
||||||
sys.wait(5) ; artificial delay
|
sys.wait(5) ; artificial delay
|
||||||
|
Loading…
Reference in New Issue
Block a user