mirror of
https://github.com/irmen/prog8.git
synced 2026-04-26 20:17:57 +00:00
Merge branch 'master' into structs
# Conflicts: # compiler/src/prog8/compiler/astprocessing/AstChecker.kt # examples/test.p8
This commit is contained in:
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',' ' -> {
|
||||
|
||||
@@ -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',' ' -> {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user