mirror of
https://github.com/irmen/prog8.git
synced 2024-10-19 07:23:56 +00:00
273 lines
8.0 KiB
Lua
273 lines
8.0 KiB
Lua
%import textio
|
|
%import syslib
|
|
|
|
; Note: this code is compatible with C64 and CX16.
|
|
|
|
diskio {
|
|
|
|
|
|
sub directory(ubyte drivenumber) -> ubyte {
|
|
; -- Shows the directory contents of disk drive 8-11 (provide as argument). Returns success flag.
|
|
|
|
c64.SETNAM(1, "$")
|
|
c64.SETLFS(1, drivenumber, 0)
|
|
void c64.OPEN() ; open 1,8,0,"$"
|
|
if_cs
|
|
goto io_error
|
|
void c64.CHKIN(1) ; use #1 as input channel
|
|
if_cs
|
|
goto io_error
|
|
|
|
repeat 4 {
|
|
void c64.CHRIN() ; skip the 4 prologue bytes
|
|
}
|
|
|
|
; while not key pressed / EOF encountered, read data.
|
|
ubyte status = c64.READST()
|
|
while not status {
|
|
ubyte low = c64.CHRIN()
|
|
ubyte high = c64.CHRIN()
|
|
txt.print_uw(mkword(high, low))
|
|
txt.chrout(' ')
|
|
ubyte @zp char
|
|
do {
|
|
char = c64.CHRIN()
|
|
txt.chrout(char)
|
|
} until char==0
|
|
txt.chrout('\n')
|
|
void c64.CHRIN() ; skip 2 bytes
|
|
void c64.CHRIN()
|
|
status = c64.READST()
|
|
void c64.STOP()
|
|
if_nz
|
|
break
|
|
}
|
|
|
|
io_error:
|
|
status = c64.READST()
|
|
c64.CLRCHN() ; restore default i/o devices
|
|
c64.CLOSE(1)
|
|
|
|
if status and status != 64 { ; 64=end of file
|
|
txt.print("\ni/o error, status: ")
|
|
txt.print_ub(status)
|
|
txt.chrout('\n')
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
|
|
; TODO make a listfiles() call that accepts a callback routine to process the file entries. This avoids the need to allocate and pass all those buffers.
|
|
|
|
sub listfiles(ubyte drivenumber, uword pattern, ubyte suffixmatch,
|
|
uword namesarray, uword blocksarray, uword namesbuffer, ubyte maxnum) -> ubyte {
|
|
; -- returns a list of files in the directory matching the given prefix or suffix (optional)
|
|
; their blocksizes will be put into the blocksarray
|
|
; pointers to their names will be put into the namesarray
|
|
; The namesbuffer should be at least 17 * maxnum and both arrays should be at least maxnum size as well.
|
|
if maxnum==0 return 0
|
|
|
|
ubyte num_files = 0
|
|
ubyte pattern_size = 0
|
|
if pattern!=0
|
|
pattern_size = strlen(pattern)
|
|
|
|
c64.SETNAM(1, "$")
|
|
c64.SETLFS(1, drivenumber, 0)
|
|
void c64.OPEN() ; open 1,8,0,"$"
|
|
if_cs
|
|
goto close_end
|
|
void c64.CHKIN(1) ; use #1 as input channel
|
|
if_cs
|
|
goto close_end
|
|
|
|
repeat 4 {
|
|
void c64.CHRIN() ; skip the 4 prologue bytes
|
|
}
|
|
|
|
ubyte disk_name = true
|
|
uword last_filename_ptr = namesbuffer
|
|
|
|
while not c64.READST() {
|
|
@(blocksarray) = c64.CHRIN()
|
|
@(blocksarray+1) = c64.CHRIN()
|
|
|
|
; read until the filename starts after the first "
|
|
while c64.CHRIN()!='\"' {
|
|
if c64.READST()
|
|
goto close_end
|
|
}
|
|
|
|
; append the filename to the buffer
|
|
repeat {
|
|
ubyte char = c64.CHRIN()
|
|
if char==0
|
|
break
|
|
; if_z
|
|
; break ; TODO fix generated code for this jump
|
|
if char=='\"'
|
|
break
|
|
@(namesbuffer) = char
|
|
namesbuffer++
|
|
}
|
|
|
|
if disk_name
|
|
namesbuffer = last_filename_ptr
|
|
else {
|
|
@(namesbuffer) = 0
|
|
namesbuffer++
|
|
ubyte matches = true
|
|
if pattern_size {
|
|
; do filename matching
|
|
if suffixmatch
|
|
rightstr(last_filename_ptr, filename, pattern_size)
|
|
else
|
|
leftstr(last_filename_ptr, filename, pattern_size)
|
|
matches = strcmp(filename, pattern)==0
|
|
}
|
|
if matches {
|
|
; enter the details into the arrays and increment
|
|
num_files++
|
|
@(namesarray) = lsb(last_filename_ptr)
|
|
@(namesarray+1) = msb(last_filename_ptr)
|
|
last_filename_ptr = namesbuffer
|
|
namesarray += 2
|
|
blocksarray += 2
|
|
if num_files>=maxnum
|
|
goto close_end
|
|
} else {
|
|
; no match, reset buffer to overwrite previous
|
|
namesbuffer = last_filename_ptr
|
|
}
|
|
}
|
|
|
|
; read the rest of the entry until the end
|
|
do {
|
|
ubyte char2 = c64.CHRIN()
|
|
char2++ ; TODO fix condition test problem with ldx
|
|
} until char2==1
|
|
|
|
void c64.CHRIN() ; skip 2 bytes
|
|
void c64.CHRIN()
|
|
disk_name = false
|
|
}
|
|
|
|
close_end:
|
|
c64.CLRCHN() ; restore default i/o devices
|
|
c64.CLOSE(1)
|
|
return num_files
|
|
}
|
|
|
|
sub status(ubyte drivenumber) {
|
|
; -- display the disk drive's current status message
|
|
c64.SETNAM(0, filename)
|
|
c64.SETLFS(15, drivenumber, 15)
|
|
void c64.OPEN() ; open 15,8,15
|
|
if_cs
|
|
goto io_error
|
|
void c64.CHKIN(15) ; use #15 as input channel
|
|
if_cs
|
|
goto io_error
|
|
|
|
while not c64.READST()
|
|
txt.chrout(c64.CHRIN())
|
|
|
|
io_error:
|
|
c64.CLRCHN() ; restore default i/o devices
|
|
c64.CLOSE(15)
|
|
}
|
|
|
|
|
|
sub save(ubyte drivenumber, uword filenameptr, uword address, uword size) -> ubyte {
|
|
c64.SETNAM(strlen(filenameptr), filenameptr)
|
|
c64.SETLFS(1, drivenumber, 0)
|
|
uword end_address = address + size
|
|
|
|
%asm {{
|
|
lda address
|
|
sta P8ZP_SCRATCH_W1
|
|
lda address+1
|
|
sta P8ZP_SCRATCH_W1+1
|
|
stx P8ZP_SCRATCH_REG
|
|
lda #<P8ZP_SCRATCH_W1
|
|
ldx end_address
|
|
ldy end_address+1
|
|
jsr c64.SAVE
|
|
php
|
|
ldx P8ZP_SCRATCH_REG
|
|
plp
|
|
}}
|
|
|
|
ubyte result=0
|
|
if_cc
|
|
result = c64.READST()==0
|
|
|
|
c64.CLRCHN()
|
|
c64.CLOSE(1)
|
|
|
|
return result
|
|
}
|
|
|
|
sub load(ubyte drivenumber, uword filenameptr, uword address_override) -> uword {
|
|
c64.SETNAM(strlen(filenameptr), filenameptr)
|
|
ubyte secondary = 1
|
|
uword end_of_load = 0
|
|
if address_override
|
|
secondary = 0
|
|
c64.SETLFS(1, drivenumber, secondary)
|
|
%asm {{
|
|
stx P8ZP_SCRATCH_REG
|
|
lda #0
|
|
ldx address_override
|
|
ldy address_override+1
|
|
jsr c64.LOAD
|
|
bcs +
|
|
stx end_of_load
|
|
sty end_of_load+1
|
|
+ ldx P8ZP_SCRATCH_REG
|
|
}}
|
|
|
|
c64.CLRCHN()
|
|
c64.CLOSE(1)
|
|
|
|
if end_of_load
|
|
return end_of_load - address_override
|
|
|
|
return 0
|
|
}
|
|
|
|
|
|
str filename = "0:??????????????????????????????????????"
|
|
|
|
sub delete(ubyte drivenumber, uword filenameptr) {
|
|
; -- delete a file on the drive
|
|
ubyte flen = strlen(filenameptr)
|
|
filename[0] = 's'
|
|
filename[1] = ':'
|
|
memcopy(filenameptr, &filename+2, flen+1)
|
|
c64.SETNAM(flen+2, filename)
|
|
c64.SETLFS(1, drivenumber, 15)
|
|
void c64.OPEN()
|
|
c64.CLRCHN()
|
|
c64.CLOSE(1)
|
|
}
|
|
|
|
sub rename(ubyte drivenumber, uword oldfileptr, uword newfileptr) {
|
|
; -- rename a file on the drive
|
|
ubyte flen_old = strlen(oldfileptr)
|
|
ubyte flen_new = strlen(newfileptr)
|
|
filename[0] = 'r'
|
|
filename[1] = ':'
|
|
memcopy(newfileptr, &filename+2, flen_new)
|
|
filename[flen_new+2] = '='
|
|
memcopy(oldfileptr, &filename+3+flen_new, flen_old+1)
|
|
c64.SETNAM(3+flen_new+flen_old, filename)
|
|
c64.SETLFS(1, drivenumber, 15)
|
|
void c64.OPEN()
|
|
c64.CLRCHN()
|
|
c64.CLOSE(1)
|
|
}
|
|
}
|