added cx16 example: automatons.

added debug mode and RTC to cx16 emulator launchers.
dt error details.
This commit is contained in:
Irmen de Jong 2024-01-12 20:18:41 +01:00
parent 0c1018ec61
commit 3b199a2a87
10 changed files with 133 additions and 13 deletions

View File

@ -9,6 +9,13 @@ This is a structured programming language for the 8-bit 6502/6510/65c02 micropro
as used in many home computers from that era. It is a medium to low level programming language,
which aims to provide many conveniences over raw assembly code (even when using a macro assembler).
**Want to buy me a coffee or a pizza perhaps?**
This project was created over the last couple of years by dedicating thousands of hours of my free time to it, to make it the best I possibly can.
If you like Prog8, and think it's worth a nice cup of hot coffee or a delicious pizza,
you can help me out a little bit over at [ko-fi.com/irmen](https://ko-fi.com/irmen).
Documentation
-------------
Full documentation (syntax reference, how to use the language and the compiler, etc.) can be found at:

View File

@ -38,7 +38,7 @@ class CX16MachineDefinition: IMachineDefinition {
when(selectedEmulator) {
1 -> {
emulator = "x16emu"
extraArgs = emptyList()
extraArgs = listOf("-debug")
}
2 -> {
emulator = "box16"
@ -51,7 +51,7 @@ class CX16MachineDefinition: IMachineDefinition {
}
println("\nStarting Commander X16 emulator $emulator...")
val cmdline = listOf(emulator, "-scale", "2", "-run", "-prg", "${programNameWithPath}.prg") + extraArgs
val cmdline = listOf(emulator, "-scale", "2", "-rtc", "-run", "-prg", "${programNameWithPath}.prg") + extraArgs
val processb = ProcessBuilder(cmdline).inheritIO()
processb.environment()["PULSE_LATENCY_MSEC"] = "10"
val process: Process = processb.start()

View File

@ -110,6 +110,7 @@ class TestCompilerOnExamplesCx16: FunSpec({
"sprites/dragons",
"amiga",
"audio",
"automatons",
"bdmusic",
"bobs",
"bubbleuniverse",

View File

@ -58,12 +58,11 @@ class Program(val name: String,
val entrypoint: Subroutine
get() {
val mainBlocks = allBlocks.filter { it.name=="main" }
return when (mainBlocks.size) {
0 -> throw FatalAstException("no 'main' block")
1 -> mainBlocks[0].subScope("start") as Subroutine
else -> throw FatalAstException("more than one 'main' block")
}
val mainBlock = allBlocks.firstOrNull { it.name=="main" }
if(mainBlock!=null)
return mainBlock.subScope("start") as? Subroutine ?: throw FatalAstException("no 'main.start' subroutine")
else
throw FatalAstException("no 'main' block")
}
val toplevelModule: Module

View File

@ -40,7 +40,13 @@ class CallGraph(private val program: Program) : IAstVisitor {
used.add(target)
}
used + blocksFromLibraries + program.entrypoint.definingBlock
// warning: it's possible that we still have a faulty program without
// a proper main.start entrypoint, so be cautiuous about it.
val main = program.allBlocks.firstOrNull { it.name=="main" }
if(main?.subScope("start") != null)
used + blocksFromLibraries + main
else
used + blocksFromLibraries
}
private val usedModules: Set<Module> by lazy {

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -30,11 +30,18 @@ You can compile programs for various machines with this CPU:
Prog8 is copyright © Irmen de Jong (irmen@razorvine.net | http://www.razorvine.net).
The project is on github: https://github.com/irmen/prog8.git
**License:**
This software is free to use, as defined in the GNU GPL 3.0 (https://www.gnu.org/licenses/gpl.html)
Software License
^^^^^^^^^^^^^^^^
This is free software, as defined in the GNU GPL 3.0 (https://www.gnu.org/licenses/gpl.html)
*Exception:* All output files generated by the compiler (intermediary files and compiled binary programs)
are excluded from this and you can do with those *whatever you want*.
This means, for instance, that you can use the Prog8 compiler to create commercial software as long as only sell *the actual resulting program*.
are excluded from this particular license: you can do with those *whatever you want*.
This means, for instance, that you can use the Prog8 compiler to create commercial software as long as you only sell *the actual resulting program*.
Want to buy me a coffee or a pizza perhaps?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This project was created over the last couple of years by dedicating thousands of hours of my free time to it, to make it the best I possibly can.
If you like Prog8, and think it's worth a nice cup of hot coffee or a delicious pizza,
you can help me out a little bit over at https://ko-fi.com/irmen .
.. image:: _static/cube3d.png
@ -47,6 +54,17 @@ This means, for instance, that you can use the Prog8 compiler to create commerci
:width: 33%
:alt: Fully playable tetris clone
.. image:: _static/rrgame.png
:width: 33%
:alt: BoulderDash(tm) clone for the X16
.. image:: _static/x16paint.png
:width: 33%
:alt: Paint program for the X16
.. image:: _static/x16chess.png
:width: 33%
:alt: Chess program for the X16
Language features
-----------------

View File

@ -0,0 +1,89 @@
; Wolfram's Cellular Automatons.
%import math
%import conv
%import textio
%option no_sysinit
%zeropage basicsafe
main {
ubyte rulenumber
bool[256] cells_previous
bool[256] cells
sub start() {
void cx16.screen_mode(128, false)
setup()
txt.clear_screen()
print_title(rulenumber)
init_automaton(rulenumber)
ubyte y
for y in 32 to 199+32 {
cx16.FB_cursor_position((320-len(cells))/2,y)
cx16.FB_set_pixels(cells, len(cells))
cells_previous = cells
ubyte @zp x
for x in 0 to len(cells)-1 {
cells[x] = generate(x) ; next generation
}
}
}
sub setup() {
str userinput = "?"*10
txt.print("\n\nwolfram's cellular automatons.\n\n")
txt.print("suggestions for interesting rules:\n 30, 45, 90, 110, 117, 184.\n\n")
txt.print("enter rule number, 0-255: ")
void txt.input_chars(userinput)
rulenumber = conv.str2ubyte(userinput)
txt.print("\nstart state: (r)andomize or (s)ingle? ")
void txt.input_chars(userinput)
if userinput[0]=='r' {
for cx16.r0L in 0 to len(cells)-1
cells[cx16.r0L] = math.rnd() >= 128
} else {
cells[len(cells)/2] = true
}
}
sub print_title(ubyte number) {
cx16.FB_cursor_position(92,16)
for cx16.r9L in "Cellular Automaton #" {
cx16.GRAPH_put_next_char(cx16.r9L)
}
conv.str_ub(number)
for cx16.r9L in conv.string_out {
cx16.GRAPH_put_next_char(cx16.r9L)
}
}
bool[8] states
sub init_automaton(ubyte number) {
ubyte state
for state in 0 to 7 {
number >>=1
if_cs
states[state] = true
else
states[state] = false
}
}
sub generate(ubyte x) -> bool {
ubyte pattern = 0
if cells_previous[x-1]
pattern |= %100
if cells_previous[x]
pattern |= %010
if cells_previous[x+1]
pattern |= %001
return states[pattern]
}
}