Merge branch 'master' into structs

# Conflicts:
#	compiler/src/prog8/compiler/astprocessing/AstChecker.kt
#	examples/test.p8
This commit is contained in:
Irmen de Jong
2025-05-23 19:00:59 +02:00
24 changed files with 290 additions and 118 deletions
@@ -19,7 +19,7 @@ class ConfigurableZeropage(
init {
if (options.floats) {
TODO("floats")
TODO("floats in configurable target zp")
}
if(SCRATCH_REG!=SCRATCH_B1+1u)
@@ -30,7 +30,7 @@ class ConfigurableZeropage(
ZeropageType.FULL -> fullsafe.forEach { free.addAll(it) }
ZeropageType.BASICSAFE -> basicsafe.forEach { free.addAll(it) }
ZeropageType.KERNALSAFE -> kernalsafe.forEach { free.addAll(it) }
ZeropageType.FLOATSAFE -> TODO("floatsafe")
ZeropageType.FLOATSAFE -> TODO("floatsafe in configurable target zp")
}
val distinctFree = free.distinct()
@@ -512,7 +512,7 @@ private fun optimizeJsrRtsAndOtherCombinations(linesByFour: Sequence<List<Indexe
// rts + jmp -> remove jmp
// rts + bxx -> remove bxx
// lda + cmp #0 -> remove cmp, same for cpy and cpx.
// bra/jmp + bra/jmp -> remove second bra/jmp
// bra/jmp + bra/jmp -> remove second bra/jmp (bra bra / jmp jmp are not removed because this is likely a jump table!)
// and some other optimizations.
val mods = mutableListOf<Modification>()
@@ -569,10 +569,13 @@ private fun optimizeJsrRtsAndOtherCombinations(linesByFour: Sequence<List<Indexe
}
}
if(" bra" in first || "\tbra" in first || " jmp" in first || "\tjmp" in first ) {
if(" bra" in second || "\tbra" in second || " jmp" in second || "\tjmp" in second ) {
mods.add(Modification(lines[1].index, true, null))
}
// only remove bra followed by jmp or jmp followed by bra
// bra bra or jmp jmp is likely part of a jump table, which should keep all entries!
if((" bra" in first || "\tbra" in first) && (" jmp" in second || "\tjmp" in second)) {
mods.add(Modification(lines[1].index, true, null))
}
if((" jmp" in first || "\tjmp" in first) && (" bra" in second || "\tbra" in second)) {
mods.add(Modification(lines[1].index, true, null))
}
}
@@ -1266,7 +1266,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
}
private fun loadStatusAsBooleanResult(branchForTrue: Opcode, result: MutableList<IRCodeChunkBase>): Int {
// TODO this used to be a single instruction like SCC, SCS, SZ etc but those were problematic
// TODO this used to be a single instruction like SCC, SCS, SZ etc
val other = codeGen.createLabelName()
val after = codeGen.createLabelName()
val resultReg = codeGen.registers.next(IRDataType.BYTE)
@@ -1281,7 +1281,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
}
private fun compareRegisterAsBooleanResult(branchForTrue: Opcode, dt: IRDataType, reg1: Int, reg2: Int, result: MutableList<IRCodeChunkBase>): Int {
// TODO this used to be a single instruction like SCC, SCS, SZ etc but those were problematic
// TODO this used to be a single instruction like SCC, SCS, SZ etc
val other = codeGen.createLabelName()
val after = codeGen.createLabelName()
val resultReg = codeGen.registers.next(IRDataType.BYTE)
@@ -1970,7 +1970,7 @@ class IRCodeGen(
null -> when(registerOrFlag.statusflag) {
// TODO: do the statusflag argument as last
Statusflag.Pc -> chunk += IRInstruction(Opcode.LSR, paramDt, reg1=resultReg)
else -> throw AssemblyError("weird statusflag as param")
else -> throw AssemblyError("unsupported statusflag as param")
}
else -> throw AssemblyError("unsupported register arg")
}
+101 -28
View File
@@ -22,18 +22,23 @@ monogfx {
const ubyte MODE_STIPPLE = %00000001
const ubyte MODE_INVERT = %00000010
uword buffer_visible, buffer_back
sub lores() {
; enable 320*240 bitmap mode
buffer_visible = buffer_back = $0000
cx16.VERA_CTRL=0
cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1
cx16.VERA_DC_HSCALE = 64
cx16.VERA_DC_VSCALE = 64
cx16.VERA_L1_CONFIG = %00000100
cx16.VERA_L1_MAPBASE = 0
cx16.VERA_L1_TILEBASE = 0
cx16.VERA_L1_TILEBASE = 0 ; lores
width = 320
height = 240
lores_mode = true
buffer_visible = buffer_back = $0000
mode = MODE_NORMAL
clear_screen(false)
}
@@ -46,14 +51,40 @@ monogfx {
cx16.VERA_DC_VSCALE = 128
cx16.VERA_L1_CONFIG = %00000100
cx16.VERA_L1_MAPBASE = 0
cx16.VERA_L1_TILEBASE = %00000001
cx16.VERA_L1_TILEBASE = %00000001 ; hires
width = 640
height = 480
lores_mode = false
buffer_visible = buffer_back = $0000
mode = MODE_NORMAL
clear_screen(false)
}
sub enable_doublebuffer() {
; enable double buffering mode
if lores_mode {
buffer_visible = $0000
buffer_back = $2800
} else {
buffer_visible = $0000
buffer_back = $9800
}
}
sub swap_buffers(bool wait_for_vsync) {
; flip the buffers: make the back buffer visible and the other one now the backbuffer.
; to avoid any screen tearing it is advised to call this during the vertical blank (pass true)
if wait_for_vsync
sys.waitvsync()
cx16.r0 = buffer_back
buffer_back = buffer_visible
buffer_visible = cx16.r0
cx16.VERA_CTRL = 0
cx16.r0 &= %1111110000000000
cx16.VERA_L1_TILEBASE = cx16.VERA_L1_TILEBASE & 1 | (cx16.r0H >>1 )
}
sub textmode() {
; back to normal text mode
cx16.r15L = cx16.VERA_DC_VIDEO & %00000111 ; retain chroma + output mode
@@ -559,6 +590,7 @@ drawmode: ora cx16.r15L
sub disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, bool draw) {
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
; Midpoint algorithm, filled
; Note: has problems with INVERT draw mode because of horizontal span overdrawing. Horizontal lines may occur.
if radius==0
return
ubyte @zp yy = 0
@@ -597,6 +629,7 @@ drawmode: ora cx16.r15L
sub safe_disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, bool draw) {
; Does bounds checking and clipping.
; Midpoint algorithm, filled
; Note: has problems with INVERT draw mode because of horizontal span overdrawing. Horizontal lines may occur.
if radius==0
return
ubyte @zp yy = 0
@@ -672,8 +705,7 @@ nostipple:
invert:
prepare()
%asm {{
lda cx16.VERA_DATA0
eor p8v_maskbits,y
eor cx16.VERA_DATA0
sta cx16.VERA_DATA0
}}
return
@@ -696,7 +728,7 @@ invert:
adc p8v_times40_lsb,y
sta cx16.VERA_ADDR_L
lda p8v_times40_msb,y
adc #0
adc p8v_buffer_back+1
sta cx16.VERA_ADDR_M
lda p8v_xx
@@ -708,18 +740,29 @@ invert:
; width=640 (hires)
%asm {{
stz cx16.VERA_CTRL
stz cx16.VERA_ADDR_H
lda p8v_xx
and #7
pha ; xbits
; xx /= 8
lsr p8v_xx+1
ror p8v_xx
lsr p8v_xx+1
ror p8v_xx
lsr p8v_xx
}}
xx /= 8
;xx /= 8
xx += yy*(640/8)
%asm {{
lda p8v_xx+1
sta cx16.VERA_ADDR_M
lda p8v_xx
sta cx16.VERA_ADDR_L
lda p8v_xx+1
clc
adc p8v_buffer_back+1
sta cx16.VERA_ADDR_M
lda #0
rol a ; hi bit carry also needed when double-buffering
sta cx16.VERA_ADDR_H
plx ; xbits
lda p8v_maskbits,x
}}
@@ -761,11 +804,15 @@ invert:
%asm {{
stz cx16.VERA_CTRL
stz cx16.VERA_ADDR_H
lda p8v_xx+1
sta cx16.VERA_ADDR_M
lda p8v_xx
sta cx16.VERA_ADDR_L
lda p8v_xx+1
clc
adc p8v_buffer_back+1
sta cx16.VERA_ADDR_M
lda #0
rol a ; hi bit carry also needed when double-buffering
sta cx16.VERA_ADDR_H
ply ; xbits
lda p8s_plot.p8v_maskbits,y
and cx16.VERA_DATA0
@@ -848,8 +895,8 @@ skip:
}
sub fill_scanline_right() {
; TODO maybe this could use vera auto increment, but that requires some clever masking calculations
cx16.r9s = xx
; TODO maybe this could use vera auto increment, but that requires some clever masking calculations
cx16.r9s = xx
while xx <= width-1 {
if pgetset()
break
@@ -884,11 +931,15 @@ skip:
%asm {{
stz cx16.VERA_CTRL
stz cx16.VERA_ADDR_H
lda p8v_xpos+1
sta cx16.VERA_ADDR_M
lda p8v_xpos
sta cx16.VERA_ADDR_L
lda p8v_xpos+1
clc
adc p8v_buffer_back+1
sta cx16.VERA_ADDR_M
lda #0
rol a ; hi bit carry also needed when double-buffering
sta cx16.VERA_ADDR_H
ply ; xbits
lda p8s_plot.p8v_maskbits,y
and cx16.VERA_DATA0
@@ -935,12 +986,12 @@ _doplot beq +
ror a
lsr a
lsr a
clc
ldy p8v_yy
clc
adc p8v_times40_lsb,y
sta cx16.VERA_ADDR_L
lda p8v_times40_msb,y
adc #0
adc p8v_buffer_back+1
sta cx16.VERA_ADDR_M
lda #%00010000 ; autoincr
sta cx16.VERA_ADDR_H
@@ -948,7 +999,33 @@ _doplot beq +
}
else {
cx16.r0 = yy*(640/8)
cx16.vaddr(0, cx16.r0+(xx/8), 0, 1)
;cx16.r0 += xx/8
%asm {{
ldy p8v_xx+1
lda p8v_xx
sty P8ZP_SCRATCH_B1
lsr P8ZP_SCRATCH_B1
ror a
lsr P8ZP_SCRATCH_B1
ror a
lsr a
clc
adc cx16.r0
sta cx16.r0
bcc +
inc cx16.r0+1
+
stz cx16.VERA_CTRL
lda cx16.r0L
sta cx16.VERA_ADDR_L
lda cx16.r0H
clc
adc p8v_buffer_back+1
sta cx16.VERA_ADDR_M
lda #%00001000 ; autoincr (1 bit shifted)
rol a ; hi bit carry also needed when double-buffering
sta cx16.VERA_ADDR_H
}}
}
return
}
@@ -1116,15 +1193,11 @@ cdraw_mod2 ora cx16.VERA_DATA1
cmp #0
beq +
lda #255
+ ldy #80
- sta cx16.VERA_DATA0
sta cx16.VERA_DATA0
sta cx16.VERA_DATA0
sta cx16.VERA_DATA0
sta cx16.VERA_DATA0
sta cx16.VERA_DATA0
sta cx16.VERA_DATA0
+ ldy #40
-
.rept 16
sta cx16.VERA_DATA0
.endrept
dey
bne -
rts
+33 -2
View File
@@ -474,7 +474,7 @@ extsub $ff68 = mouse_config(byte shape @A, ubyte resX @X, ubyte resY @Y) clobbe
extsub $ff6b = mouse_get(ubyte zdataptr @X) -> ubyte @A, byte @X ; use mouse_pos() instead
extsub $ff71 = mouse_scan() clobbers(A, X, Y)
extsub $ff53 = joystick_scan() clobbers(A, X, Y)
extsub $ff56 = joystick_get(ubyte joynr @A) -> uword @AX, bool @Y ; note: everything is inverted
extsub $ff56 = joystick_get(ubyte joynr @A) -> uword @AX, bool @Y ; note: everything is inverted even the boolean present flag. Also see detect_joysticks() and get_all_joysticks()
; X16Edit (rom bank 13/14 but you ideally should use the routine search_x16edit() to search for the correct bank)
extsub $C000 = x16edit_default() clobbers(A,X,Y)
@@ -1168,8 +1168,39 @@ asmsub restore_vera_context() clobbers(A) {
}}
}
sub joysticks_detect() -> ubyte {
; returns bits 0-4, set to 1 if that joystick is present.
; bit 0 = keyboard joystick, bit 1 - 4 = joypads 1 to 4
cx16.r0H = 255
for cx16.r0L in 4 downto 0 {
void cx16.joystick_get(cx16.r0L)
%asm {{
cpy #1 ; present?
}}
rol(cx16.r0H)
}
return ~cx16.r0H
}
; Commander X16 IRQ dispatcher routines
sub joysticks_getall(bool also_keyboard_js) -> uword {
; returns combined pressed buttons from all connected joysticks
; note: returns the 'normal' not inverted status bits for the buttons (1 = button pressed.)
cx16.r0H = 1
if also_keyboard_js
cx16.r0H = 0
cx16.r1 = $ffff
for cx16.r0L in cx16.r0H to 4 {
bool notpresent
cx16.r2, notpresent = cx16.joystick_get(cx16.r0L)
if not notpresent {
cx16.r1 &= cx16.r2
}
}
return ~cx16.r1
}
; Commander X16 IRQ dispatcher routines
inline asmsub disable_irqs() clobbers(A) {
; Disable all Vera IRQ sources. Note that it does NOT set the CPU IRQ disabled status bit!
+2 -3
View File
@@ -231,9 +231,8 @@ sys {
if_cs
cx16.r0L |= 1
; TODO: overflow flag not yet supported
; if_vs
; cx16.r0L |= %01000000
if_vs
cx16.r0L |= %01000000
return cx16.r0L
}
@@ -200,7 +200,7 @@ internal class AstChecker(private val program: Program,
val iterableDt = forLoop.iterable.inferType(program).getOrUndef()
if(iterableDt.isNumeric) TODO("iterable type should not be simple numeric!? "+forLoop.position)
if(iterableDt.isNumeric) TODO("iterable type should not be simple numeric "+forLoop.position)
if(forLoop.iterable is IFunctionCall) {
errors.err("can not loop over function call return value", forLoop.position)
@@ -213,7 +213,7 @@ internal class AstChecker(private val program: Program,
} else {
when (loopvar.datatype.base) {
BaseDataType.UBYTE -> {
if (!iterableDt.isUnsignedByte && !iterableDt.isUnsignedByteArray && !iterableDt.isString) // TODO remove ubyte check?
if (!iterableDt.isUnsignedByte && !iterableDt.isUnsignedByteArray && !iterableDt.isString)
errors.err("ubyte loop variable can only loop over unsigned bytes or strings", forLoop.position)
checkUnsignedLoopDownto0(forLoop.iterable as? RangeExpression)
}
@@ -224,7 +224,7 @@ internal class AstChecker(private val program: Program,
}
BaseDataType.UWORD -> {
if (!iterableDt.isUnsignedByte && !iterableDt.isUnsignedWord && !iterableDt.isString && // TODO remove byte and word check?
if (!iterableDt.isUnsignedByte && !iterableDt.isUnsignedWord && !iterableDt.isString &&
!iterableDt.isUnsignedByteArray && !iterableDt.isUnsignedWordArray &&
!iterableDt.isSplitWordArray
)
@@ -234,7 +234,7 @@ internal class AstChecker(private val program: Program,
}
BaseDataType.BYTE -> {
if (!iterableDt.isSignedByte && !iterableDt.isSignedByteArray) // TODO remove byte check?
if (!iterableDt.isSignedByte && !iterableDt.isSignedByteArray)
errors.err("byte loop variable can only loop over bytes", forLoop.position)
}
@@ -1,5 +1,6 @@
Prog8 compiler v11.3.1 by Irmen de Jong (irmen@razorvine.net)
Prog8 compiler v12.0-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
Prerelease version from git commit cc063124 in branch master
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
Compiling program import-all-c128.p8
@@ -1,5 +1,6 @@
Prog8 compiler v11.3.1 by Irmen de Jong (irmen@razorvine.net)
Prog8 compiler v12.0-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
Prerelease version from git commit cc063124 in branch master
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
Compiling program import-all-c64.p8
@@ -1,5 +1,6 @@
Prog8 compiler v11.3.1 by Irmen de Jong (irmen@razorvine.net)
Prog8 compiler v12.0-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
Prerelease version from git commit cc063124 in branch master
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
Compiling program import-all-cx16.p8
@@ -530,6 +531,7 @@ LIBRARY MODULE NAME: monogfx
----------------------------
monogfx {
uword buffer_visible, buffer_back
const ubyte MODE_INVERT
const ubyte MODE_NORMAL
const ubyte MODE_STIPPLE
@@ -545,6 +547,7 @@ monogfx {
cs_innerloop640 (bool draw @A) -> clobbers (Y)
disc (uword xcenter, uword ycenter, ubyte radius, bool draw)
drawmode (ubyte dm)
enable_doublebuffer ()
fill (uword x, uword y, bool draw, ubyte stack_rambank)
fillrect (uword xx, uword yy, uword rwidth, uword rheight, bool draw)
hires ()
@@ -560,6 +563,7 @@ monogfx {
safe_disc (uword xcenter, uword ycenter, ubyte radius, bool draw)
safe_horizontal_line (uword xx, uword yy, uword length, bool draw)
safe_plot (uword xx, uword yy, bool draw)
swap_buffers (bool wait_for_vsync)
text (uword xx, uword yy, bool draw, str sctextptr)
text_charset (ubyte charset)
textmode ()
@@ -1093,6 +1097,8 @@ cx16 {
iso_cursor_char (ubyte character @X) -> clobbers (A,X,Y)
joystick_get (ubyte joynr @A) -> uword @AX, bool @Y = $ff56
joystick_scan () -> clobbers (A,X,Y) = $ff53
joysticks_detect () -> ubyte
joysticks_getall (bool also_keyboard_js) -> uword
kbdbuf_get_modifiers () -> ubyte @A = $fec0
kbdbuf_peek () -> ubyte @A, ubyte @X = $febd
kbdbuf_put (ubyte key @A) -> clobbers (X) = $fec3
@@ -1,5 +1,6 @@
Prog8 compiler v11.3.1 by Irmen de Jong (irmen@razorvine.net)
Prog8 compiler v12.0-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
Prerelease version from git commit cc063124 in branch master
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
Compiling program import-all-pet32.p8
@@ -1,5 +1,6 @@
Prog8 compiler v11.3.1 by Irmen de Jong (irmen@razorvine.net)
Prog8 compiler v12.0-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
Prerelease version from git commit cc063124 in branch master
This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
Compiling program import-all-virtual.p8
+2 -1
View File
@@ -816,6 +816,7 @@ Full-screen lores or hires monochrome bitmap graphics routines, available on the
- two resolutions: lores 320*240 or hires 640*480 bitmap mode
- optimized routines for monochrome (2-color) graphics
- clearing screen, switching screen mode, also back to text mode
- doublebuffering option to avoid flicker
- drawing and reading individual pixels
- drawing lines, rectangles, filled rectangles, circles, discs
- flood fill
@@ -823,7 +824,7 @@ Full-screen lores or hires monochrome bitmap graphics routines, available on the
- can draw using a stipple pattern (alternate black/white pixels) and in invert mode (toggle pixels)
Read the `monogfx source code <https://github.com/irmen/prog8/tree/master/compiler/res/prog8lib/cx16/monogfx.p8>`_
to see what's in there.
and the `testmonogfx` example program, to see what's in there.
palette (cx16 only)
+1 -1
View File
@@ -74,6 +74,7 @@ Future Things and Ideas
- is "checkAssignmentCompatible" redundant (gets called just 1 time!) when we also have "checkValueTypeAndRange" ?
- enums?
- romable: should we have a way to explicitly set the memory address for the BSS area (instead of only the highram bank number on X16, allow a memory address too for the -varshigh option?)
- romable: fix remaining codegens (some for loops, see ForLoopsAsmGen)
- Kotlin: can we use inline value classes in certain spots?
- add float support to the configurable compiler targets
- 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
@@ -124,7 +125,6 @@ Libraries
---------
- Add split-word array sorting routines to sorting module?
- Add double-array sorting routines to sorting module? (that allows you to sort a second array in sync with the array of numbers)
- cx16: _irq_dispatcher now only dispatches a single irq source, better to ROL/BCC to handle *all* possible (multiple) sources.
- See if the raster interrupt handler on the C64 can be tweaked to be a more stable raster irq
- pet32 target: make syslib more complete (missing kernal routines)?
- need help with: PET disk routines (OPEN, SETLFS etc are not exposed as kernal calls)
+28 -50
View File
@@ -1,12 +1,10 @@
%import textio
%import syslib
%import conv
%import math
%import monogfx
%import verafx
; %import gfx_lores
; 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???
@@ -17,23 +15,25 @@ main {
uword angley
uword anglez
cx16.set_screen_mode($80)
cx16.GRAPH_init(0)
cx16.GRAPH_set_colors(13, 6, 6)
cx16.GRAPH_clear()
monogfx.lores()
monogfx.text_charset(1)
monogfx.clear_screen(false)
print_ship_name()
monogfx.enable_doublebuffer()
monogfx.clear_screen(false)
print_ship_name()
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)
; We use verafx to clear the screen during animation, instead of
; the regular routine. This speeds up the frame rate a bit.
verafx.clear(0, monogfx.buffer_back + 320*16/8, 0, 320/8*220/4)
; monogfx.clear_screen(false)
; sys.waitvsync()
cx16.GRAPH_set_colors(1, 0, 0)
draw_lines_hiddenremoval()
; draw_lines()
monogfx.swap_buffers(true)
anglex += 317
angley -= 505
@@ -42,33 +42,19 @@ main {
}
sub print_ship_name() {
cx16.r0 = 32
cx16.r1 = 8
ubyte c
for c in "ship: "
cx16.GRAPH_put_next_char(c)
for c in shipdata.shipName
cx16.GRAPH_put_next_char(c)
monogfx.text(20, 0, true, "3d ship model: ")
monogfx.text(140, 0, true, shipdata.shipName)
cx16.r0 += 16
print_number_gfx(shipdata.totalNumberOfPoints)
for c in " vertices, "
cx16.GRAPH_put_next_char(c)
print_number_gfx(shipdata.totalNumberOfEdges)
for c in " edges, "
cx16.GRAPH_put_next_char(c)
print_number_gfx(shipdata.totalNumberOfFaces)
for c in " faces"
cx16.GRAPH_put_next_char(c)
monogfx.text(60, 8, true, conv.str_ub(shipdata.totalNumberOfPoints))
monogfx.text(80, 8, true, "vertices,")
monogfx.text(160, 8, true, conv.str_ub(shipdata.totalNumberOfEdges))
monogfx.text(180, 8, true, "edges,")
monogfx.text(240, 8, true, conv.str_ub(shipdata.totalNumberOfFaces))
monogfx.text(260, 8, true, "faces")
}
sub print_number_gfx(ubyte num) {
uword num_str = conv.str_ub(num)
do {
cx16.GRAPH_put_next_char(@(num_str))
num_str++
} until @(num_str)==0
}
const uword screen_width = 320
const ubyte screen_height = 240
@@ -81,15 +67,11 @@ main {
ubyte @zp vTo = shipdata.edgesTo[i]
word persp1 = 200 + matrix_math.rotatedz[vFrom]/256
word persp2 = 200 + matrix_math.rotatedz[vTo]/256
cx16.GRAPH_draw_line(matrix_math.rotatedx[vFrom] / persp1 + screen_width/2 as uword,
monogfx.line(matrix_math.rotatedx[vFrom] / persp1 + screen_width/2 as uword,
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)
matrix_math.rotatedy[vTo] / persp2 + screen_height/2 as uword,
true)
}
}
@@ -149,15 +131,11 @@ main {
ubyte vTo = shipdata.edgesTo[edgeidx]
word persp1 = 170 + matrix_math.rotatedz[vFrom]/256
word persp2 = 170 + matrix_math.rotatedz[vTo]/256
cx16.GRAPH_draw_line(matrix_math.rotatedx[vFrom] / persp1 + screen_width/2 as uword,
monogfx.line(matrix_math.rotatedx[vFrom] / persp1 + screen_width/2 as uword,
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)
matrix_math.rotatedy[vTo] / persp2 + screen_height/2 as uword,
true)
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
50 END
1000 POKE$400,ASC("*"):POKE$401,0 : REM PATTERN
1010 POKE$30E,4:POKE$30C,0:SYS$A00C : REM SELECT
1010 POKE$30E,4:POKE$30C,0:SYS$A009 : REM SELECT
1020 ADDR=PEEK($30E)*256+PEEK($30C):F$="" : REM FILENAME
1030 C=PEEK(ADDR):IFC=0 THEN RETURN
1040 F$=F$+CHR$(C):ADDR=ADDR+1:GOTO 1030
+22 -2
View File
@@ -14,7 +14,6 @@
; ZERO PAGE LOCATIONS USED: R0-R5,R15 ($02-$0d and $20-$21), $7a-$7f are used but are saved and restored. (can be checked with -dumpvars)
; TODO joystick control? mouse control?
; TODO keyboard typing; jump to the first entry that starts with that character? (but 'q' for quit stops working then, plus scrolling with pageup/down is already pretty fast)
main {
@@ -38,7 +37,7 @@ main {
fileselector {
; these buffer sizes are chosen to fill up the rest of the hiram bank after the fileselector code
const uword filenamesbuf_size = $e40
const uword filenamesbuf_size = $d80
const ubyte max_num_files = 128
uword @shared filenamesbuffer = memory("filenames_buffer", filenamesbuf_size, 0)
@@ -191,6 +190,27 @@ fileselector {
return 0
ubyte key = cbm.GETIN2()
cx16.r0 = cx16.joysticks_getall(false)
if cx16.r0L!=0
sys.wait(4)
ror(cx16.r0L)
if_cs
key = ']' ; right
ror(cx16.r0L)
if_cs
key = '[' ; left
ror(cx16.r0L)
if_cs
key = 17 ; down
ror(cx16.r0L)
if_cs
key = 145 ; up
if cx16.r0L & $0f != 0
key = '\n' ; select file
if cx16.r0H != 0
key = 27 ; cancel
when key {
3, 27 -> return 0 ; STOP and ESC aborts
'\n',' ' -> {
+21 -1
View File
@@ -11,7 +11,6 @@
; Returns the name of the selected file. If it is a directory instead, the name will start and end with a slash '/'.
; Works in PETSCII mode and in ISO mode as well (no case folding in ISO mode!)
; TODO joystick control? mouse control?
; TODO keyboard typing; jump to the first entry that starts with that character? (but 'q' for quit stops working then, plus scrolling with pageup/down is already pretty fast)
@@ -186,6 +185,27 @@ fileselector {
return 0
ubyte key = cbm.GETIN2()
cx16.r0 = cx16.joysticks_getall(false)
if cx16.r0L!=0
sys.wait(4)
ror(cx16.r0L)
if_cs
key = ']' ; right
ror(cx16.r0L)
if_cs
key = '[' ; left
ror(cx16.r0L)
if_cs
key = 17 ; down
ror(cx16.r0L)
if_cs
key = 145 ; up
if cx16.r0L & $0f != 0
key = '\n' ; select file
if cx16.r0H != 0
key = 27 ; cancel
when key {
3, 27 -> return 0 ; STOP and ESC aborts
'\n',' ' -> {
+39 -3
View File
@@ -1,6 +1,6 @@
%import monogfx
%import textio
%import math
%import conv
%option no_sysinit
%zeropage basicsafe
@@ -18,8 +18,7 @@ main {
sys.wait(2*60)
demo2()
monogfx.textmode()
txt.print("done!\n")
doublebuffer.demo()
}
sub demofill() {
@@ -214,3 +213,40 @@ main {
}
}
doublebuffer {
sub demo() {
monogfx.lores()
monogfx.text_charset(1)
monogfx.enable_doublebuffer()
uword cx = 100
repeat {
monogfx.clear_screen(false)
monogfx.text(50, 10, true, iso:"Double Buffered")
monogfx.circle(160, 120, 100, true)
monogfx.disc(160, 120, 40, true)
monogfx.rect(40, 40, 240, 180, true)
monogfx.drawmode(monogfx.MODE_STIPPLE)
monogfx.fill(50, 50, true, 1)
monogfx.drawmode(monogfx.MODE_NORMAL)
monogfx.fill(250, 50, true, 1)
monogfx.fillrect( 10, 50, 20, 100, true)
monogfx.line(10, 10, 300, 200, true)
repeat 200 {
monogfx.plot($00e0 + math.randrange(64), 20 + math.randrange(20), true)
}
monogfx.circle(cx, 219, 20, true)
monogfx.text(cx+20, 225, true, conv.str_uw(cx))
cx++
monogfx.swap_buffers(true)
}
}
}
@@ -132,8 +132,8 @@ class IRFileReader {
zeropage,
zpReserved,
zpAllowed,
false, // TODO always false?
false, // TODO always false?
false,
false,
romable,
target,
loadAddress,
@@ -1036,7 +1036,7 @@ data class IRInstruction(
if(opcode==Opcode.CONCAT)
return when(type) {
IRDataType.BYTE -> IRDataType.WORD
IRDataType.WORD -> TODO("concat.w from long type")
IRDataType.WORD -> TODO("concat.w into long type")
else -> null
}
if(opcode==Opcode.ASRNM || opcode==Opcode.LSRNM || opcode==Opcode.LSLNM || opcode==Opcode.SQRT)
@@ -402,7 +402,7 @@ class PtTypeCast(type: DataType, position: Position) : PtExpression(type, positi
if(children[0] is PtIdentifier) {
copy.add((children[0] as PtIdentifier).copy())
} else {
TODO("cannot copy node ${children[0]}")
TODO("copy node ${children[0]}")
}
return copy
}
@@ -400,7 +400,8 @@ class VirtualMachine(irProgram: IRProgram) {
status = status or 0b00000010u
if(statusCarry)
status = status or 0b00000001u
// TODO overflow not yet supported
if(statusOverflow)
status = status or 0b01000000u
valueStack.add(status)
nextPc()
}
@@ -410,7 +411,7 @@ class VirtualMachine(irProgram: IRProgram) {
statusNegative = status and 0b10000000 != 0
statusZero = status and 0b00000010 != 0
statusCarry = status and 0b00000001 != 0
// TODO overflow not yet supported
statusOverflow = status and 0b01000000 != 0
nextPc()
}
@@ -1385,7 +1386,7 @@ class VirtualMachine(irProgram: IRProgram) {
IRDataType.WORD -> statusNegative = (comparison and 0x8000)!=0
IRDataType.FLOAT -> { /* floats don't change the status bits */ }
}
// TODO statusOverflow
// TODO determine statusOverflow in comparison
}
private fun plusMinusMultAnyByte(operator: String, reg1: Int, reg2: Int) {