mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
implemented a couple more diskio routines for the VM target
This commit is contained in:
parent
eef8ae00b8
commit
3a9919a377
@ -8,8 +8,12 @@ diskio {
|
||||
|
||||
sub directory() -> bool {
|
||||
; -- Prints the directory contents to the screen. Returns success.
|
||||
txt.print("@TODO: directory\n")
|
||||
return false
|
||||
%ir {{
|
||||
loadm.w r65534,diskio.load.filenameptr
|
||||
loadm.w r65535,diskio.load.address_override
|
||||
syscall 61 (): r0.b
|
||||
returnr.b r0
|
||||
}}
|
||||
}
|
||||
|
||||
sub list_filenames(uword pattern_ptr, uword filenames_buffer, uword filenames_buf_size) -> ubyte {
|
||||
@ -18,7 +22,7 @@ diskio {
|
||||
; After the last filename one additional 0 byte is placed to indicate the end of the list.
|
||||
; Returns number of files (it skips 'dir' entries i.e. subdirectories).
|
||||
; Also sets carry on exit: Carry clear = all files returned, Carry set = directory has more files that didn't fit in the buffer.
|
||||
txt.print("@TODO: list_flienames\n")
|
||||
txt.print("@TODO: list_filenames\n")
|
||||
sys.clear_carry()
|
||||
return 0
|
||||
}
|
||||
@ -115,17 +119,51 @@ diskio {
|
||||
|
||||
; ---- other functions ----
|
||||
|
||||
sub chdir(str path) {
|
||||
; -- change current directory.
|
||||
txt.print("@TODO: chdir\n")
|
||||
}
|
||||
|
||||
sub mkdir(str name) {
|
||||
; -- make a new subdirectory.
|
||||
txt.print("@TODO: mkdir\n")
|
||||
}
|
||||
|
||||
sub rmdir(str name) {
|
||||
; -- remove a subdirectory.
|
||||
txt.print("@TODO: rmdir\n")
|
||||
}
|
||||
|
||||
sub curdir() -> uword {
|
||||
; return current directory name or 0 if error
|
||||
txt.print("@TODO: curdir\n")
|
||||
return 0
|
||||
}
|
||||
|
||||
sub status() -> str {
|
||||
; -- retrieve the disk drive's current status message
|
||||
return "ok"
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
sub save(uword filenameptr, uword start_address, uword savesize) -> bool {
|
||||
%ir {{
|
||||
load.b r65532,0
|
||||
loadm.w r65533,diskio.save.filenameptr
|
||||
loadm.w r65534,diskio.save.start_address
|
||||
loadm.w r65535,diskio.save.savesize
|
||||
syscall 58 (r65533.w, r65534.w, r65535.w): r0.b
|
||||
syscall 58 (r65532.b, r65533.w, r65534.w, r65535.w): r0.b
|
||||
returnr.b r0
|
||||
}}
|
||||
}
|
||||
|
||||
; like save() but omits the 2 byte prg header.
|
||||
sub save_raw(uword filenameptr, uword startaddress, uword savesize) -> bool {
|
||||
%ir {{
|
||||
load.b r65532,1
|
||||
loadm.w r65533,diskio.save.filenameptr
|
||||
loadm.w r65534,diskio.save.start_address
|
||||
loadm.w r65535,diskio.save.savesize
|
||||
syscall 58 (r65532.b, r65533.w, r65534.w, r65535.w): r0.b
|
||||
returnr.b r0
|
||||
}}
|
||||
}
|
||||
@ -167,6 +205,10 @@ diskio {
|
||||
|
||||
sub rename(uword oldfileptr, uword newfileptr) {
|
||||
; -- rename a file on the drive
|
||||
txt.print("@TODO: rename\n")
|
||||
%ir {{
|
||||
loadm.w r65534,diskio.rename.oldfileptr
|
||||
loadm.w r65535,diskio.rename.newfileptr
|
||||
syscall 60 (r65534.w, r65535.w)
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ Compiler:
|
||||
- OR.... make all this more generic and use some %segment option to create real segments for 64tass?
|
||||
- (need separate step in codegen and IR to write the "golden" variables)
|
||||
|
||||
- VM: implement more diskio support
|
||||
- do we need (array)variable alignment tag instead of block alignment tag? You want to align the data, not the code in the block?
|
||||
- ir: related to the one above: block alignment doesn't translate well to variables in the block (the actual stuff that needs to be aligned in memory) but: need variable alignment tag instead of block alignment tag, really
|
||||
- ir: fix call() return value handling
|
||||
@ -55,6 +54,7 @@ Libraries:
|
||||
- fix the problems in atari target, and flesh out its libraries.
|
||||
- c128 target: make syslib more complete (missing kernal routines)?
|
||||
- pet32 target: make syslib more complete (missing kernal routines)?
|
||||
- VM: implement more diskio support
|
||||
|
||||
|
||||
Optimizations:
|
||||
|
@ -3,6 +3,8 @@ package prog8.vm
|
||||
import prog8.intermediate.FunctionCallArgs
|
||||
import prog8.intermediate.IRDataType
|
||||
import java.io.File
|
||||
import kotlin.io.path.Path
|
||||
import kotlin.io.path.listDirectoryEntries
|
||||
import kotlin.math.*
|
||||
|
||||
/*
|
||||
@ -68,6 +70,8 @@ SYSCALLS:
|
||||
57 = load_raw
|
||||
58 = save
|
||||
59 = delete
|
||||
60 = rename
|
||||
61 = directory
|
||||
*/
|
||||
|
||||
enum class Syscall {
|
||||
@ -130,7 +134,9 @@ enum class Syscall {
|
||||
LOAD,
|
||||
LOAD_RAW,
|
||||
SAVE,
|
||||
DELETE
|
||||
DELETE,
|
||||
RENAME,
|
||||
DIRECTORY
|
||||
;
|
||||
|
||||
companion object {
|
||||
@ -632,41 +638,79 @@ object SysCalls {
|
||||
Syscall.LOAD -> {
|
||||
val (filenameA, addrA) = getArgValues(callspec.arguments, vm)
|
||||
val filename = vm.memory.getString((filenameA as UShort).toInt())
|
||||
val data = File(filename).readBytes()
|
||||
val addr = if(addrA==0) data[0] + data[1]*256 else (addrA as UShort).toInt()
|
||||
for(i in 0..<data.size-2) {
|
||||
vm.memory.setUB(addr+i, data[i+2].toUByte())
|
||||
if(File(filename).exists()) {
|
||||
val data = File(filename).readBytes()
|
||||
val addr = if (addrA == 0) data[0] + data[1] * 256 else (addrA as UShort).toInt()
|
||||
for (i in 0..<data.size - 2) {
|
||||
vm.memory.setUB(addr + i, data[i + 2].toUByte())
|
||||
}
|
||||
vm.registers.setUW(0, (addr + data.size - 2).toUShort())
|
||||
} else {
|
||||
vm.registers.setUW(0, 0u)
|
||||
}
|
||||
vm.registers.setUW(0, (addr+data.size-2).toUShort())
|
||||
}
|
||||
Syscall.LOAD_RAW -> {
|
||||
val (filenameA, addrA) = getArgValues(callspec.arguments, vm)
|
||||
val filename = vm.memory.getString((filenameA as UShort).toInt())
|
||||
val addr = (addrA as UShort).toInt()
|
||||
val data = File(filename).readBytes()
|
||||
for(i in 0..<data.size) {
|
||||
vm.memory.setUB(addr+i, data[i].toUByte())
|
||||
if(File(filename).exists()) {
|
||||
val data = File(filename).readBytes()
|
||||
for (i in 0..<data.size) {
|
||||
vm.memory.setUB(addr + i, data[i].toUByte())
|
||||
}
|
||||
vm.registers.setUW(0, (addr + data.size).toUShort())
|
||||
} else {
|
||||
vm.registers.setUW(0, 0u)
|
||||
}
|
||||
vm.registers.setUW(0, (addr+data.size).toUShort())
|
||||
}
|
||||
Syscall.SAVE -> {
|
||||
val (filenamePtr, startA, sizeA) = getArgValues(callspec.arguments, vm)
|
||||
val (raw, filenamePtr, startA, sizeA) = getArgValues(callspec.arguments, vm)
|
||||
val size = (sizeA as UShort).toInt()
|
||||
val data = ByteArray(size+2)
|
||||
val startPtr = (startA as UShort).toInt()
|
||||
data[0] = (startPtr and 255).toByte()
|
||||
data[1] = (startPtr shr 8).toByte()
|
||||
for(i in 0..<size) {
|
||||
data[i+2] = vm.memory.getUB(startPtr+i).toByte()
|
||||
val data: ByteArray
|
||||
if(raw==0) {
|
||||
// save with 2 byte PRG load address header
|
||||
data = ByteArray(size+2)
|
||||
data[0] = (startPtr and 255).toByte()
|
||||
data[1] = (startPtr shr 8).toByte()
|
||||
for (i in 0..<size) {
|
||||
data[i + 2] = vm.memory.getUB(startPtr + i).toByte()
|
||||
}
|
||||
} else {
|
||||
// 'raw' save, without header
|
||||
data = ByteArray(size)
|
||||
for (i in 0..<size) {
|
||||
data[i] = vm.memory.getUB(startPtr + i).toByte()
|
||||
}
|
||||
}
|
||||
val filename = vm.memory.getString((filenamePtr as UShort).toInt())
|
||||
File(filename).writeBytes(data)
|
||||
if (File(filename).exists())
|
||||
vm.registers.setUB(0, 0u)
|
||||
else {
|
||||
File(filename).writeBytes(data)
|
||||
vm.registers.setUB(0, 1u)
|
||||
}
|
||||
}
|
||||
Syscall.DELETE -> {
|
||||
val filenamePtr = getArgValues(callspec.arguments, vm).single() as UShort
|
||||
val filename = vm.memory.getString(filenamePtr.toInt())
|
||||
File(filename).delete()
|
||||
}
|
||||
Syscall.RENAME -> {
|
||||
val (origFilenamePtr, newFilenamePtr) = getArgValues(callspec.arguments, vm)
|
||||
val origFilename = vm.memory.getString((origFilenamePtr as UShort).toInt())
|
||||
val newFilename = vm.memory.getString((newFilenamePtr as UShort).toInt())
|
||||
File(origFilename).renameTo(File(newFilename))
|
||||
}
|
||||
Syscall.DIRECTORY -> {
|
||||
// no arguments
|
||||
val directory = Path(".")
|
||||
println("Directory listing for ${directory.toAbsolutePath().normalize()}")
|
||||
directory.listDirectoryEntries().sorted().forEach {
|
||||
println("${it.toFile().length()}\t${it.normalize()}")
|
||||
}
|
||||
vm.registers.setUB(0, 1u)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user