mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 19:54:26 +00:00
Merge branch 'master' into split-arrays
This commit is contained in:
commit
e18119e24c
@ -4,6 +4,6 @@
|
|||||||
<option name="jvmTarget" value="11" />
|
<option name="jvmTarget" value="11" />
|
||||||
</component>
|
</component>
|
||||||
<component name="KotlinJpsPluginSettings">
|
<component name="KotlinJpsPluginSettings">
|
||||||
<option name="version" value="1.8.20-release-327" />
|
<option name="version" value="1.8.21-release-380" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -1,5 +1,6 @@
|
|||||||
package prog8tests.codegencpu6502
|
package prog8tests.codegencpu6502
|
||||||
|
|
||||||
|
import io.kotest.assertions.throwables.shouldNotThrowAny
|
||||||
import io.kotest.core.spec.style.FunSpec
|
import io.kotest.core.spec.style.FunSpec
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import prog8.code.SymbolTableMaker
|
import prog8.code.SymbolTableMaker
|
||||||
@ -102,5 +103,14 @@ class TestCodegen: FunSpec({
|
|||||||
result.name shouldBe "test"
|
result.name shouldBe "test"
|
||||||
Files.deleteIfExists(Path("${result.name}.asm"))
|
Files.deleteIfExists(Path("${result.name}.asm"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("64tass assembler available? - if this fails you need to install 64tass in the path") {
|
||||||
|
val command = mutableListOf("64tass", "--version")
|
||||||
|
shouldNotThrowAny {
|
||||||
|
val proc = ProcessBuilder(command).inheritIO().start()
|
||||||
|
val result = proc.waitFor()
|
||||||
|
result.shouldBe(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -188,6 +188,19 @@ _longcopy
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline asmsub irqsafe_set_irqd() {
|
||||||
|
%asm {{
|
||||||
|
php
|
||||||
|
sei
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline asmsub irqsafe_clear_irqd() {
|
||||||
|
%asm {{
|
||||||
|
plp
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
inline asmsub exit(ubyte returnvalue @A) {
|
inline asmsub exit(ubyte returnvalue @A) {
|
||||||
; -- immediately exit the program with a return code in the A register
|
; -- immediately exit the program with a return code in the A register
|
||||||
; TODO
|
; TODO
|
||||||
|
@ -729,6 +729,19 @@ _longcopy
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline asmsub irqsafe_set_irqd() {
|
||||||
|
%asm {{
|
||||||
|
php
|
||||||
|
sei
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline asmsub irqsafe_clear_irqd() {
|
||||||
|
%asm {{
|
||||||
|
plp
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
inline asmsub exit(ubyte returnvalue @A) {
|
inline asmsub exit(ubyte returnvalue @A) {
|
||||||
; -- immediately exit the program with a return code in the A register
|
; -- immediately exit the program with a return code in the A register
|
||||||
%asm {{
|
%asm {{
|
||||||
|
@ -695,6 +695,19 @@ _longcopy
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline asmsub irqsafe_set_irqd() {
|
||||||
|
%asm {{
|
||||||
|
php
|
||||||
|
sei
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline asmsub irqsafe_clear_irqd() {
|
||||||
|
%asm {{
|
||||||
|
plp
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
inline asmsub exit(ubyte returnvalue @A) {
|
inline asmsub exit(ubyte returnvalue @A) {
|
||||||
; -- immediately exit the program with a return code in the A register
|
; -- immediately exit the program with a return code in the A register
|
||||||
%asm {{
|
%asm {{
|
||||||
|
@ -155,6 +155,9 @@ gfx2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub horizontal_line(uword x, uword y, uword length, ubyte color) {
|
sub horizontal_line(uword x, uword y, uword length, ubyte color) {
|
||||||
|
ubyte[9] masked_ends = [ 0, %10000000, %11000000, %11100000, %11110000, %11111000, %11111100, %11111110, %11111111]
|
||||||
|
ubyte[9] masked_starts = [ 0, %00000001, %00000011, %00000111, %00001111, %00011111, %00111111, %01111111, %11111111]
|
||||||
|
|
||||||
if length==0
|
if length==0
|
||||||
return
|
return
|
||||||
when active_mode {
|
when active_mode {
|
||||||
@ -163,12 +166,13 @@ gfx2 {
|
|||||||
ubyte separate_pixels = (8-lsb(x)) & 7
|
ubyte separate_pixels = (8-lsb(x)) & 7
|
||||||
if separate_pixels as uword > length
|
if separate_pixels as uword > length
|
||||||
separate_pixels = lsb(length)
|
separate_pixels = lsb(length)
|
||||||
repeat separate_pixels {
|
if separate_pixels {
|
||||||
; TODO optimize this by writing a masked byte in 1 go
|
position(x,y)
|
||||||
plot(x, y, color)
|
cx16.VERA_ADDR_H &= %00000111 ; vera auto-increment off
|
||||||
x++
|
cx16.VERA_DATA0 = cx16.VERA_DATA0 | masked_starts[separate_pixels]
|
||||||
}
|
|
||||||
length -= separate_pixels
|
length -= separate_pixels
|
||||||
|
x += separate_pixels
|
||||||
|
}
|
||||||
if length {
|
if length {
|
||||||
position(x, y)
|
position(x, y)
|
||||||
separate_pixels = lsb(length) & 7
|
separate_pixels = lsb(length) & 7
|
||||||
@ -205,11 +209,9 @@ _loop lda length
|
|||||||
bra _loop
|
bra _loop
|
||||||
_done
|
_done
|
||||||
}}
|
}}
|
||||||
repeat separate_pixels {
|
|
||||||
; TODO optimize this by writing a masked byte in 1 go
|
cx16.VERA_ADDR_H &= %00000111 ; vera auto-increment off
|
||||||
plot(x, y, color)
|
cx16.VERA_DATA0 = cx16.VERA_DATA0 | masked_ends[separate_pixels]
|
||||||
x++
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
cx16.VERA_ADDR_H &= %00000111 ; vera auto-increment off again
|
cx16.VERA_ADDR_H &= %00000111 ; vera auto-increment off again
|
||||||
}
|
}
|
||||||
@ -366,8 +368,14 @@ _done
|
|||||||
return
|
return
|
||||||
position2(x,y,true)
|
position2(x,y,true)
|
||||||
set_both_strides(13) ; 160 increment = 1 line in 640 px 4c mode
|
set_both_strides(13) ; 160 increment = 1 line in 640 px 4c mode
|
||||||
color &= 3
|
;; color &= 3
|
||||||
color <<= gfx2.plot.shift4c[lsb(x) & 3] ; TODO with lookup table
|
;; color <<= gfx2.plot.shift4c[lsb(x) & 3]
|
||||||
|
cx16.r2L = lsb(x) & 3
|
||||||
|
when color & 3 {
|
||||||
|
1 -> color = gfx2.plot.shiftedleft_4c_1[cx16.r2L]
|
||||||
|
2 -> color = gfx2.plot.shiftedleft_4c_2[cx16.r2L]
|
||||||
|
3 -> color = gfx2.plot.shiftedleft_4c_3[cx16.r2L]
|
||||||
|
}
|
||||||
ubyte @shared mask = gfx2.plot.mask4c[lsb(x) & 3]
|
ubyte @shared mask = gfx2.plot.mask4c[lsb(x) & 3]
|
||||||
repeat lheight {
|
repeat lheight {
|
||||||
%asm {{
|
%asm {{
|
||||||
@ -547,10 +555,13 @@ _done
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub plot(uword @zp x, uword y, ubyte color) {
|
sub plot(uword @zp x, uword @zp y, ubyte @zp color) {
|
||||||
ubyte[8] @shared bits = [128, 64, 32, 16, 8, 4, 2, 1]
|
ubyte[8] @shared bits = [128, 64, 32, 16, 8, 4, 2, 1]
|
||||||
ubyte[4] @shared mask4c = [%00111111, %11001111, %11110011, %11111100]
|
ubyte[4] @shared mask4c = [%00111111, %11001111, %11110011, %11111100]
|
||||||
ubyte[4] @shared shift4c = [6,4,2,0]
|
ubyte[4] @shared shift4c = [6,4,2,0]
|
||||||
|
ubyte[4] shiftedleft_4c_1 = [1<<6, 1<<4, 1<<2, 1<<0]
|
||||||
|
ubyte[4] shiftedleft_4c_2 = [2<<6, 2<<4, 2<<2, 2<<0]
|
||||||
|
ubyte[4] shiftedleft_4c_3 = [3<<6, 3<<4, 3<<2, 3<<0]
|
||||||
|
|
||||||
when active_mode {
|
when active_mode {
|
||||||
1 -> {
|
1 -> {
|
||||||
@ -643,8 +654,13 @@ _done
|
|||||||
; TODO also mostly usable for lores 4c?
|
; TODO also mostly usable for lores 4c?
|
||||||
void addr_mul_24_for_highres_4c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
|
void addr_mul_24_for_highres_4c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
|
||||||
cx16.r2L = lsb(x) & 3 ; xbits
|
cx16.r2L = lsb(x) & 3 ; xbits
|
||||||
color &= 3
|
; color &= 3
|
||||||
color <<= shift4c[cx16.r2L] ; TODO with lookup table
|
; color <<= shift4c[cx16.r2L]
|
||||||
|
when color & 3 {
|
||||||
|
1 -> color = shiftedleft_4c_1[cx16.r2L]
|
||||||
|
2 -> color = shiftedleft_4c_2[cx16.r2L]
|
||||||
|
3 -> color = shiftedleft_4c_3[cx16.r2L]
|
||||||
|
}
|
||||||
%asm {{
|
%asm {{
|
||||||
stz cx16.VERA_CTRL
|
stz cx16.VERA_CTRL
|
||||||
lda cx16.r1L
|
lda cx16.r1L
|
||||||
@ -743,13 +759,130 @@ _done
|
|||||||
sta cx16.r0L
|
sta cx16.r0L
|
||||||
}}
|
}}
|
||||||
cx16.r1L = lsb(x) & 3
|
cx16.r1L = lsb(x) & 3
|
||||||
cx16.r0L >>= gfx2.plot.shift4c[cx16.r1L] ; TODO with lookup table
|
cx16.r0L >>= gfx2.plot.shift4c[cx16.r1L]
|
||||||
return cx16.r0L & 3
|
return cx16.r0L & 3
|
||||||
}
|
}
|
||||||
else -> return 0
|
else -> return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub fill(word @zp x, word @zp y, ubyte new_color) {
|
||||||
|
; Non-recursive scanline flood fill.
|
||||||
|
; based loosely on code found here https://www.codeproject.com/Articles/6017/QuickFill-An-efficient-flood-fill-algorithm
|
||||||
|
; with the fixes applied to the seedfill_4 routine as mentioned in the comments.
|
||||||
|
const ubyte MAXDEPTH = 48
|
||||||
|
word[MAXDEPTH] @shared stack_xl
|
||||||
|
word[MAXDEPTH] @shared stack_xr
|
||||||
|
word[MAXDEPTH] @shared stack_y
|
||||||
|
byte[MAXDEPTH] @shared stack_dy
|
||||||
|
cx16.r12L = 0 ; stack pointer
|
||||||
|
word x1
|
||||||
|
word x2
|
||||||
|
byte dy
|
||||||
|
cx16.r10L = new_color
|
||||||
|
sub push_stack(word sxl, word sxr, word sy, byte sdy) {
|
||||||
|
if cx16.r12L==MAXDEPTH
|
||||||
|
return
|
||||||
|
cx16.r0s = sy+sdy
|
||||||
|
if cx16.r0s>=0 and cx16.r0s<=height-1 {
|
||||||
|
;; stack_xl[cx16.r12L] = sxl
|
||||||
|
;; stack_xr[cx16.r12L] = sxr
|
||||||
|
;; stack_y[cx16.r12L] = sy
|
||||||
|
;; stack_dy[cx16.r12L] = sdy
|
||||||
|
;; cx16.r12L++
|
||||||
|
%asm {{
|
||||||
|
lda cx16.r12L
|
||||||
|
asl a
|
||||||
|
tay
|
||||||
|
lda sxl
|
||||||
|
sta stack_xl,y
|
||||||
|
lda sxl+1
|
||||||
|
sta stack_xl+1,y
|
||||||
|
lda sxr
|
||||||
|
sta stack_xr,y
|
||||||
|
lda sxr+1
|
||||||
|
sta stack_xr+1,y
|
||||||
|
lda sy
|
||||||
|
sta stack_y,y
|
||||||
|
lda sy+1
|
||||||
|
sta stack_y+1,y
|
||||||
|
ldy cx16.r12L
|
||||||
|
lda sdy
|
||||||
|
sta stack_dy,y
|
||||||
|
inc cx16.r12L
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sub pop_stack() {
|
||||||
|
;; cx16.r12L--
|
||||||
|
;; x1 = stack_xl[cx16.r12L]
|
||||||
|
;; x2 = stack_xr[cx16.r12L]
|
||||||
|
;; y = stack_y[cx16.r12L]
|
||||||
|
;; dy = stack_dy[cx16.r12L]
|
||||||
|
;; y += dy
|
||||||
|
%asm {{
|
||||||
|
dec cx16.r12L
|
||||||
|
lda cx16.r12L
|
||||||
|
asl a
|
||||||
|
tay
|
||||||
|
lda stack_xl,y
|
||||||
|
sta x1
|
||||||
|
lda stack_xl+1,y
|
||||||
|
sta x1+1
|
||||||
|
lda stack_xr,y
|
||||||
|
sta x2
|
||||||
|
lda stack_xr+1,y
|
||||||
|
sta x2+1
|
||||||
|
lda stack_y,y
|
||||||
|
sta y
|
||||||
|
lda stack_y+1,y
|
||||||
|
sta y+1
|
||||||
|
ldy cx16.r12L
|
||||||
|
lda stack_dy,y
|
||||||
|
sta dy
|
||||||
|
}}
|
||||||
|
y+=dy
|
||||||
|
}
|
||||||
|
cx16.r11L = pget(x as uword, y as uword) ; old_color
|
||||||
|
if cx16.r11L == cx16.r10L
|
||||||
|
return
|
||||||
|
if x<0 or x > width-1 or y<0 or y > height-1
|
||||||
|
return
|
||||||
|
push_stack(x, x, y, 1)
|
||||||
|
push_stack(x, x, y + 1, -1)
|
||||||
|
word left = 0
|
||||||
|
while cx16.r12L {
|
||||||
|
pop_stack()
|
||||||
|
x = x1
|
||||||
|
while x >= 0 and pget(x as uword, y as uword) == cx16.r11L {
|
||||||
|
plot(x as uword, y as uword, cx16.r10L)
|
||||||
|
x--
|
||||||
|
}
|
||||||
|
if x>= x1
|
||||||
|
goto skip
|
||||||
|
|
||||||
|
left = x + 1
|
||||||
|
if left < x1
|
||||||
|
push_stack(left, x1 - 1, y, -dy)
|
||||||
|
x = x1 + 1
|
||||||
|
|
||||||
|
do {
|
||||||
|
while x <= width-1 and pget(x as uword, y as uword) == cx16.r11L {
|
||||||
|
plot(x as uword, y as uword, cx16.r10L)
|
||||||
|
x++
|
||||||
|
}
|
||||||
|
push_stack(left, x - 1, y, dy)
|
||||||
|
if x > x2 + 1
|
||||||
|
push_stack(x2 + 1, x - 1, y, -dy)
|
||||||
|
skip:
|
||||||
|
x++
|
||||||
|
while x <= x2 and pget(x as uword, y as uword) != cx16.r11L
|
||||||
|
x++
|
||||||
|
left = x
|
||||||
|
} until x>x2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub position(uword @zp x, uword y) {
|
sub position(uword @zp x, uword y) {
|
||||||
ubyte bank
|
ubyte bank
|
||||||
when active_mode {
|
when active_mode {
|
||||||
|
@ -22,10 +22,7 @@ psg {
|
|||||||
; waveform = one of PULSE,SAWTOOTH,TRIANGLE,NOISE.
|
; waveform = one of PULSE,SAWTOOTH,TRIANGLE,NOISE.
|
||||||
; pulsewidth = 0-63. Specifies the pulse width for waveform=PULSE.
|
; pulsewidth = 0-63. Specifies the pulse width for waveform=PULSE.
|
||||||
envelope_states[voice_num] = 255
|
envelope_states[voice_num] = 255
|
||||||
%asm {{
|
sys.irqsafe_set_irqd()
|
||||||
php
|
|
||||||
sei
|
|
||||||
}}
|
|
||||||
cx16.r0 = $f9c2 + voice_num * 4
|
cx16.r0 = $f9c2 + voice_num * 4
|
||||||
cx16.VERA_CTRL = 0
|
cx16.VERA_CTRL = 0
|
||||||
cx16.VERA_ADDR_L = lsb(cx16.r0)
|
cx16.VERA_ADDR_L = lsb(cx16.r0)
|
||||||
@ -36,9 +33,7 @@ psg {
|
|||||||
cx16.VERA_DATA0 = waveform | pulsewidth
|
cx16.VERA_DATA0 = waveform | pulsewidth
|
||||||
envelope_volumes[voice_num] = mkword(volume, 0)
|
envelope_volumes[voice_num] = mkword(volume, 0)
|
||||||
envelope_maxvolumes[voice_num] = volume
|
envelope_maxvolumes[voice_num] = volume
|
||||||
%asm {{
|
sys.irqsafe_clear_irqd()
|
||||||
plp
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
; sub freq_hz(ubyte voice_num, float hertz) {
|
; sub freq_hz(ubyte voice_num, float hertz) {
|
||||||
@ -53,10 +48,7 @@ psg {
|
|||||||
; voice_num = 0-15, vera_freq = 0-65535 calculate this via the formula given in the Vera's PSG documentation.
|
; voice_num = 0-15, vera_freq = 0-65535 calculate this via the formula given in the Vera's PSG documentation.
|
||||||
; (https://github.com/x16community/x16-docs/blob/master/VERA%20Programmer's%20Reference.md)
|
; (https://github.com/x16community/x16-docs/blob/master/VERA%20Programmer's%20Reference.md)
|
||||||
; Write freq MSB first and then LSB to reduce the chance on clicks
|
; Write freq MSB first and then LSB to reduce the chance on clicks
|
||||||
%asm {{
|
sys.irqsafe_set_irqd()
|
||||||
php
|
|
||||||
sei
|
|
||||||
}}
|
|
||||||
cx16.r0 = $f9c1 + voice_num * 4
|
cx16.r0 = $f9c1 + voice_num * 4
|
||||||
cx16.VERA_CTRL = 0
|
cx16.VERA_CTRL = 0
|
||||||
cx16.VERA_ADDR_L = lsb(cx16.r0)
|
cx16.VERA_ADDR_L = lsb(cx16.r0)
|
||||||
@ -65,9 +57,7 @@ psg {
|
|||||||
cx16.VERA_DATA0 = msb(vera_freq)
|
cx16.VERA_DATA0 = msb(vera_freq)
|
||||||
cx16.VERA_ADDR_L--
|
cx16.VERA_ADDR_L--
|
||||||
cx16.VERA_DATA0 = lsb(vera_freq)
|
cx16.VERA_DATA0 = lsb(vera_freq)
|
||||||
%asm {{
|
sys.irqsafe_clear_irqd()
|
||||||
plp
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub volume(ubyte voice_num, ubyte vol) {
|
sub volume(ubyte voice_num, ubyte vol) {
|
||||||
|
@ -70,8 +70,10 @@ asmsub RDTIM16() -> uword @AY {
|
|||||||
; -- like RDTIM() but only returning the lower 16 bits in AY for convenience. Also avoids ram bank issue for irqs.
|
; -- like RDTIM() but only returning the lower 16 bits in AY for convenience. Also avoids ram bank issue for irqs.
|
||||||
%asm {{
|
%asm {{
|
||||||
phx
|
phx
|
||||||
|
php
|
||||||
sei
|
sei
|
||||||
jsr cbm.RDTIM
|
jsr cbm.RDTIM
|
||||||
|
plp
|
||||||
cli
|
cli
|
||||||
pha
|
pha
|
||||||
txa
|
txa
|
||||||
@ -924,6 +926,7 @@ asmsub set_rasterline(uword line @AY) {
|
|||||||
asmsub wait(uword jiffies @AY) {
|
asmsub wait(uword jiffies @AY) {
|
||||||
; --- wait approximately the given number of jiffies (1/60th seconds) (N or N+1)
|
; --- wait approximately the given number of jiffies (1/60th seconds) (N or N+1)
|
||||||
; note: the system irq handler has to be active for this to work as it depends on the system jiffy clock
|
; note: the system irq handler has to be active for this to work as it depends on the system jiffy clock
|
||||||
|
; note: this routine cannot be used from inside a irq handler
|
||||||
%asm {{
|
%asm {{
|
||||||
phx
|
phx
|
||||||
sta P8ZP_SCRATCH_W1
|
sta P8ZP_SCRATCH_W1
|
||||||
@ -1081,6 +1084,19 @@ _longcopy
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline asmsub irqsafe_set_irqd() {
|
||||||
|
%asm {{
|
||||||
|
php
|
||||||
|
sei
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline asmsub irqsafe_clear_irqd() {
|
||||||
|
%asm {{
|
||||||
|
plp
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
inline asmsub exit(ubyte returnvalue @A) {
|
inline asmsub exit(ubyte returnvalue @A) {
|
||||||
; -- immediately exit the program with a return code in the A register
|
; -- immediately exit the program with a return code in the A register
|
||||||
%asm {{
|
%asm {{
|
||||||
|
@ -87,6 +87,16 @@ sys (part of syslib)
|
|||||||
``clear_irqd ()``
|
``clear_irqd ()``
|
||||||
Clears the CPU status register Interrupt Disable flag.
|
Clears the CPU status register Interrupt Disable flag.
|
||||||
|
|
||||||
|
``irqsafe_set_irqd ()``
|
||||||
|
Sets the CPU status register Interrupt Disable flag, in a way that is safe to be used inside a IRQ handler.
|
||||||
|
Pair with ``irqsafe_clear_irqd()``.
|
||||||
|
|
||||||
|
``irqsafe_clear_irqd ()``
|
||||||
|
Clears the CPU status register Interrupt Disable flag, in a way that is safe to be used inside a IRQ handler.
|
||||||
|
Pair with ``irqsafe_set_irqd()``. Inside an IRQ handler this makes sure it doesn't inadvertently
|
||||||
|
clear the irqd status bit, and it can still be used inside normal code as well (where it *does* clear
|
||||||
|
the irqd status bit if it was cleared before entering).
|
||||||
|
|
||||||
``progend ()``
|
``progend ()``
|
||||||
Returns the last address of the program in memory + 1.
|
Returns the last address of the program in memory + 1.
|
||||||
Can be used to load dynamic data after the program, instead of hardcoding something.
|
Can be used to load dynamic data after the program, instead of hardcoding something.
|
||||||
@ -371,6 +381,7 @@ Full-screen multicolor bitmap graphics routines, available on the Cx16 machine o
|
|||||||
- clearing screen, switching screen mode, also back to text mode is possible.
|
- clearing screen, switching screen mode, also back to text mode is possible.
|
||||||
- drawing and reading individual pixels
|
- drawing and reading individual pixels
|
||||||
- drawing lines, rectangles, filled rectangles, circles, discs
|
- drawing lines, rectangles, filled rectangles, circles, discs
|
||||||
|
- flood fill
|
||||||
- drawing text inside the bitmap
|
- drawing text inside the bitmap
|
||||||
- in monochrome mode, it's possible to use a stippled drawing pattern to simulate a shade of gray.
|
- in monochrome mode, it's possible to use a stippled drawing pattern to simulate a shade of gray.
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@ For 9.0 major changes
|
|||||||
- DONE: for loops now skip the whole loop if from value already outside the loop range (this is what all other programming languages also do)
|
- DONE: for loops now skip the whole loop if from value already outside the loop range (this is what all other programming languages also do)
|
||||||
- DONE: asmsub params or return values passed in cpu flags (like carry) now must be declared as booleans (previously ubyte was still accepted).
|
- DONE: asmsub params or return values passed in cpu flags (like carry) now must be declared as booleans (previously ubyte was still accepted).
|
||||||
- DONE: (on cx16) added diskio.save_raw() to save without the 2 byte prg header
|
- DONE: (on cx16) added diskio.save_raw() to save without the 2 byte prg header
|
||||||
|
- DONE: added sys.irqsafe_xxx irqd routines
|
||||||
|
- DONE: added gfx2.fill() flood fill routine
|
||||||
|
|
||||||
- [much work:] add special (u)word array type (or modifier such as @fast or @split? ) that puts the array into memory as 2 separate byte-arrays 1 for LSB 1 for MSB -> allows for word arrays of length 256 and faster indexing
|
- [much work:] add special (u)word array type (or modifier such as @fast or @split? ) that puts the array into memory as 2 separate byte-arrays 1 for LSB 1 for MSB -> allows for word arrays of length 256 and faster indexing
|
||||||
this is an enormous amout of work, if this type is to be treated equally as existing (u)word , because all expression / lookup / assignment routines need to know about the distinction....
|
this is an enormous amout of work, if this type is to be treated equally as existing (u)word , because all expression / lookup / assignment routines need to know about the distinction....
|
||||||
@ -61,7 +63,6 @@ Libraries:
|
|||||||
- c64: make the graphics.BITMAP_ADDRESS configurable (VIC banking)
|
- c64: make the graphics.BITMAP_ADDRESS configurable (VIC banking)
|
||||||
- optimize several inner loops in gfx2 even further?
|
- optimize several inner loops in gfx2 even further?
|
||||||
- add modes 3 and perhaps even 2 to gfx2 (lores 16 color and 4 color)?
|
- add modes 3 and perhaps even 2 to gfx2 (lores 16 color and 4 color)?
|
||||||
- add a flood fill (span fill/scanline fill) routine to gfx2?
|
|
||||||
|
|
||||||
|
|
||||||
Expressions:
|
Expressions:
|
||||||
|
@ -9,8 +9,10 @@
|
|||||||
main {
|
main {
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
gfx2.screen_mode(4)
|
||||||
|
demofill()
|
||||||
|
sys.wait(2*60)
|
||||||
gfx2.screen_mode(5)
|
gfx2.screen_mode(5)
|
||||||
|
|
||||||
demo1()
|
demo1()
|
||||||
sys.wait(2*60)
|
sys.wait(2*60)
|
||||||
demo2()
|
demo2()
|
||||||
@ -19,6 +21,21 @@ main {
|
|||||||
txt.print("done!\n")
|
txt.print("done!\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub demofill() {
|
||||||
|
|
||||||
|
gfx2.circle(160, 120, 110, 1)
|
||||||
|
gfx2.rect(180, 5, 25, 190, 1)
|
||||||
|
gfx2.line(100, 150, 240, 10, 1)
|
||||||
|
gfx2.line(101, 150, 241, 10, 1)
|
||||||
|
;gfx2.monochrome_stipple(true)
|
||||||
|
sys.wait(60)
|
||||||
|
gfx2.fill(100,100,2)
|
||||||
|
;gfx2.monochrome_stipple(false)
|
||||||
|
gfx2.fill(182,140,3)
|
||||||
|
gfx2.fill(182,40,1)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
sub demo1() {
|
sub demo1() {
|
||||||
uword yy = 10
|
uword yy = 10
|
||||||
uword xx
|
uword xx
|
||||||
|
@ -4,4 +4,4 @@ org.gradle.parallel=true
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
javaVersion=11
|
javaVersion=11
|
||||||
kotlinVersion=1.8.20
|
kotlinVersion=1.8.21
|
||||||
|
Loading…
Reference in New Issue
Block a user