From 09cbdf410a93b2fff8e49dff7dab9a200a5785ed Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 31 Oct 2024 20:08:10 +0100 Subject: [PATCH] added diskio.exists(), made f_close_w() idempotent like f_close() already was --- compiler/res/prog8lib/cx16/diskio.p8 | 24 +++++++++++++++++++--- compiler/res/prog8lib/diskio.p8 | 27 +++++++++++++++++++++---- compiler/res/prog8lib/virtual/diskio.p8 | 12 +++++++++++ docs/source/comparing.rst | 3 ++- docs/source/todo.rst | 6 ++++++ examples/cx16/cobramk3-gfx.p8 | 22 ++++++++++++++++---- examples/test.p8 | 26 +++++++++++++++++------- virtualmachine/src/prog8/vm/SysCalls.kt | 1 + 8 files changed, 102 insertions(+), 19 deletions(-) diff --git a/compiler/res/prog8lib/cx16/diskio.p8 b/compiler/res/prog8lib/cx16/diskio.p8 index 44cad3d57..5897c232a 100644 --- a/compiler/res/prog8lib/cx16/diskio.p8 +++ b/compiler/res/prog8lib/cx16/diskio.p8 @@ -145,6 +145,7 @@ io_error: uword list_pattern uword list_blocks bool iteration_in_progress = false + bool write_iteration_in_progress = false str list_filetype = "???" ; prg, seq, dir str list_filename = "?" * 50 @@ -423,6 +424,7 @@ _end jsr cbm.READST sub f_close() { ; -- end an iterative file loading session (close channels). + ; it is safe to call this multiple times, or when no file is open for reading. if iteration_in_progress { cbm.CLRCHN() cbm.CLOSE(READ_IO_CHANNEL) @@ -460,7 +462,10 @@ _end jsr cbm.READST cbm.SETLFS(WRITE_IO_CHANNEL, drivenumber, WRITE_IO_CHANNEL) void cbm.OPEN() ; open 13,8,13,"filename" if_cc { - return cbm.READST()==0 + if cbm.READST()==0 { + write_iteration_in_progress = true + return true + } } cbm.CLOSE(WRITE_IO_CHANNEL) f_close_w() @@ -498,8 +503,12 @@ no_mciout: sub f_close_w() { ; -- end an iterative file writing session (close channels). - cbm.CLRCHN() - cbm.CLOSE(WRITE_IO_CHANNEL) + ; it is safe to call this multiple times, or when no file is open for reading. + if write_iteration_in_progress { + cbm.CLRCHN() + cbm.CLOSE(WRITE_IO_CHANNEL) + write_iteration_in_progress = false + } } @@ -869,6 +878,15 @@ io_error: send_command(list_filename) } + sub exists(str filename) -> bool { + ; -- returns true if the given file exists on the disk, otherwise false + if f_open(filename) { + f_close() + return true + } + return false + } + sub f_seek(uword pos_hiword, uword pos_loword) { ; -- seek in the reading file opened with f_open, to the given 32-bits position ; Note: this will not work if you have already read the last byte of the file! Then you must close and reopen the file first. diff --git a/compiler/res/prog8lib/diskio.p8 b/compiler/res/prog8lib/diskio.p8 index a1a2b14ca..0d9ab649e 100644 --- a/compiler/res/prog8lib/diskio.p8 +++ b/compiler/res/prog8lib/diskio.p8 @@ -124,6 +124,7 @@ io_error: uword list_pattern uword list_blocks bool iteration_in_progress = false + bool write_iteration_in_progress = false str list_filetype = "???" ; prg, seq, dir str list_filename = "?" * 50 @@ -377,6 +378,7 @@ _end jsr cbm.READST sub f_close() { ; -- end an iterative file loading session (close channels). + ; it is safe to call this multiple times, or when no file is open for reading. if iteration_in_progress { cbm.CLRCHN() cbm.CLOSE(READ_IO_CHANNEL) @@ -399,8 +401,12 @@ _end jsr cbm.READST cbm.SETNAM(string.length(filenameptr), filenameptr) cbm.SETLFS(WRITE_IO_CHANNEL, drivenumber, 1) void cbm.OPEN() ; open 13,8,1,"filename" - if_cc - return cbm.READST()==0 + if_cc { + if cbm.READST()==0 { + write_iteration_in_progress = true + return true + } + } cbm.CLOSE(WRITE_IO_CHANNEL) f_close_w() return false @@ -422,8 +428,12 @@ _end jsr cbm.READST sub f_close_w() { ; -- end an iterative file writing session (close channels). - cbm.CLRCHN() - cbm.CLOSE(WRITE_IO_CHANNEL) + ; it is safe to call this multiple times, or when no file is open for reading. + if write_iteration_in_progress { + cbm.CLRCHN() + cbm.CLOSE(WRITE_IO_CHANNEL) + write_iteration_in_progress = false + } } @@ -590,6 +600,15 @@ io_error: cbm.CLOSE(1) } + sub exists(str filename) -> bool { + ; -- returns true if the given file exists on the disk, otherwise false + if f_open(filename) { + f_close() + return true + } + return false + } + sub send_command(uword commandptr) { ; -- send a dos command to the drive cbm.SETNAM(string.length(commandptr), commandptr) diff --git a/compiler/res/prog8lib/virtual/diskio.p8 b/compiler/res/prog8lib/virtual/diskio.p8 index baf2be7b8..4e3db92e1 100644 --- a/compiler/res/prog8lib/virtual/diskio.p8 +++ b/compiler/res/prog8lib/virtual/diskio.p8 @@ -140,6 +140,7 @@ diskio { sub f_close() { ; -- end an iterative file loading session (close channels). + ; it is safe to call this multiple times, or when no file is open for reading. %ir {{ syscall 56 () }} @@ -181,6 +182,7 @@ diskio { sub f_close_w() { ; -- end an iterative file writing session (close channels). + ; it is safe to call this multiple times, or when no file is open for reading. %ir {{ syscall 57 () }} @@ -298,4 +300,14 @@ diskio { syscall 44 (r65534.w, r65535.w) }} } + + sub exists(str filename) -> bool { + ; -- returns true if the given file exists on the disk, otherwise false + if f_open(filename) { + f_close() + return true + } + return false + } + } diff --git a/docs/source/comparing.rst b/docs/source/comparing.rst index cdaa6e20c..15c115e4a 100644 --- a/docs/source/comparing.rst +++ b/docs/source/comparing.rst @@ -24,7 +24,8 @@ The language No linker --------- - Even though your programs can consist of many separate module files, the compiler always outputs a single program file. There is no separate linker step. - Currently, it's not easily possible to integrate object files created elsewhere. + Currently, it's not easily possible to integrate object files created elsewhere. If the object file has a fixed load location and fixed entrypoints, + it can be loaded explicitly and accessed easily using romsub definitions though. - The prog8 compiler is self-contained in a single jar file. You do need 1 external tool namely 64tass, which performs the assembler step. diff --git a/docs/source/todo.rst b/docs/source/todo.rst index e01eb4ac5..29e917743 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,6 +1,11 @@ TODO ==== +VM/IR: fix return value passing from %ir routines? (diskio.exists routine always returns true) + +make better zsmkit example +write a howto for integrating third party library code like zsmkit and vtui + Improve register load order in subroutine call args assignments: in certain situations, the "wrong" order of evaluation of function call arguments is done which results in overwriting registers that already got their value, which requires a lot of stack juggling (especially on plain 6502 cpu!) @@ -10,6 +15,7 @@ Maybe this routine can be made more intelligent. See usesOtherRegistersWhileEva Future Things and Ideas ^^^^^^^^^^^^^^^^^^^^^^^ - Improve the SublimeText syntax file for prog8, you can also install this for 'bat': https://github.com/sharkdp/bat?tab=readme-ov-file#adding-new-syntaxes--language-definitions +- Does it make codegen easier if everything is an expression? Start with the PtProgram ast , get rid of the statements there -> expressions that have Void data type - Can we support signed % (remainder) somehow? - IR: implement missing operators in AssignmentGen (array shifts etc) - instead of copy-pasting inline asmsubs, make them into a 64tass macro and use that instead. diff --git a/examples/cx16/cobramk3-gfx.p8 b/examples/cx16/cobramk3-gfx.p8 index 4b54c921d..154e1aeb9 100644 --- a/examples/cx16/cobramk3-gfx.p8 +++ b/examples/cx16/cobramk3-gfx.p8 @@ -3,9 +3,12 @@ %import conv %import math %import verafx +; %import gfx_lores -; TODO add all other Elite's ships, show their name, advance to next ship on keypress +; TODO add FPS counter +; TODO add double buffering ; TODO fix the camera normal calculation for the hidden surface removal +; TODO add all other Elite's ships, show their name, advance to next ship on keypress ; TODO embed pre calculated surface normals??? main { @@ -23,10 +26,11 @@ main { repeat { matrix_math.rotate_vertices(msb(anglex), msb(angley), msb(anglez)) - verafx.clear(0, 320*10, 0, 320*(220/4)) - ; cx16.GRAPH_set_colors(0, 0, 0) - ; cx16.GRAPH_draw_rect(32, 10, 256, 220, 0, true) + verafx.clear(0, 320*10, 0, 320*(220/4)) + ; cx16.GRAPH_set_colors(0, 0, 0) + ; cx16.GRAPH_draw_rect(32, 10, 256, 220, 0, true) + ; sys.waitvsync() cx16.GRAPH_set_colors(1, 0, 0) draw_lines_hiddenremoval() ; draw_lines() @@ -81,6 +85,11 @@ main { matrix_math.rotatedy[vFrom] / persp1 + screen_height/2 as uword, matrix_math.rotatedx[vTo] / persp2 + screen_width/2 as uword, matrix_math.rotatedy[vTo] / persp2 + screen_height/2 as uword) +; gfx_lores.line(matrix_math.rotatedx[vFrom] / persp1 + screen_width/2 as uword, +; matrix_math.rotatedy[vFrom] / persp1 + screen_height/2 as ubyte, +; matrix_math.rotatedx[vTo] / persp2 + screen_width/2 as uword, +; matrix_math.rotatedy[vTo] / persp2 + screen_height/2 as ubyte, +; 1) } } @@ -144,6 +153,11 @@ main { matrix_math.rotatedy[vFrom] / persp1 + screen_height/2 as uword, matrix_math.rotatedx[vTo] / persp2 + screen_width/2 as uword, matrix_math.rotatedy[vTo] / persp2 + screen_height/2 as uword) +; gfx_lores.line(matrix_math.rotatedx[vFrom] / persp1 + screen_width/2 as uword, +; matrix_math.rotatedy[vFrom] / persp1 + screen_height/2 as ubyte, +; matrix_math.rotatedx[vTo] / persp2 + screen_width/2 as uword, +; matrix_math.rotatedy[vTo] / persp2 + screen_height/2 as ubyte, +; 1) } } diff --git a/examples/test.p8 b/examples/test.p8 index 5624d78a5..775cf173d 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,18 +1,30 @@ +%import diskio %import textio -%import gfx_hires4 +;%import gfx_hires4 %option no_sysinit %zeropage basicsafe main { sub start() { - gfx_hires4.graphics_mode() - gfx_hires4.circle(300, 250, 200, 3) - gfx_hires4.rect(320, 10, 20, 200, 3) - gfx_hires4.fill(310, 310, 2) + txt.print_bool(diskio.exists("doesntexist.prg")) + txt.nl() + txt.print_bool(diskio.exists("test.prg")) + txt.nl() - repeat { - } + diskio.f_open_w("dump.bin") + diskio.f_close_w() + diskio.f_close_w() + diskio.f_close_w() + diskio.f_close_w() + +; gfx_hires4.graphics_mode() +; gfx_hires4.circle(300, 250, 200, 3) +; gfx_hires4.rect(320, 10, 20, 200, 3) +; gfx_hires4.fill(310, 310, 2) +; +; repeat { +; } } } diff --git a/virtualmachine/src/prog8/vm/SysCalls.kt b/virtualmachine/src/prog8/vm/SysCalls.kt index 4ae9f973c..4be5c27b6 100644 --- a/virtualmachine/src/prog8/vm/SysCalls.kt +++ b/virtualmachine/src/prog8/vm/SysCalls.kt @@ -156,6 +156,7 @@ object SysCalls { is Int -> value.toDouble() is Float -> value.toDouble() is Double -> value + is Boolean -> if(value) 1.0 else 0.0 else -> (value as Number).toDouble() } when(returns.dt) {