mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
Merge branch 'master' into remove_evalstack
# Conflicts: # compiler/res/prog8lib/cx16/gfx2.p8 # docs/source/todo.rst # examples/test.p8
This commit is contained in:
commit
e1b6bb154a
@ -279,6 +279,46 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
is PtPrefix -> {
|
is PtPrefix -> {
|
||||||
if(assign.target.array==null) {
|
if(assign.target.array==null) {
|
||||||
if(assign.source.datatype==assign.target.datatype) {
|
if(assign.source.datatype==assign.target.datatype) {
|
||||||
|
if(assign.source.datatype in IntegerDatatypes) {
|
||||||
|
val signed = assign.source.datatype in SignedDatatypes
|
||||||
|
if(assign.source.datatype in ByteDatatypes) {
|
||||||
|
assignExpressionToRegister(value.value, RegisterOrPair.A, signed)
|
||||||
|
when(value.operator) {
|
||||||
|
"+" -> {}
|
||||||
|
"-" -> {
|
||||||
|
if(asmgen.isTargetCpu(CpuType.CPU65c02))
|
||||||
|
asmgen.out(" eor #255 | ina")
|
||||||
|
else
|
||||||
|
asmgen.out(" eor #255 | clc | adc #1")
|
||||||
|
}
|
||||||
|
"~" -> asmgen.out(" eor #255")
|
||||||
|
"not" -> throw AssemblyError("not should have been replaced in the Ast by ==0")
|
||||||
|
else -> throw AssemblyError("invalid prefix operator")
|
||||||
|
}
|
||||||
|
assignRegisterByte(assign.target, CpuRegister.A, signed)
|
||||||
|
} else {
|
||||||
|
assignExpressionToRegister(value.value, RegisterOrPair.AY, signed)
|
||||||
|
when(value.operator) {
|
||||||
|
"+" -> {}
|
||||||
|
"-" -> {
|
||||||
|
asmgen.out("""
|
||||||
|
sec
|
||||||
|
eor #255
|
||||||
|
adc #0
|
||||||
|
pha
|
||||||
|
tya
|
||||||
|
eor #255
|
||||||
|
adc #0
|
||||||
|
tay
|
||||||
|
pla""")
|
||||||
|
}
|
||||||
|
"~" -> asmgen.out(" pha | tya | eor #255 | tay | pla | eor #255")
|
||||||
|
"not" -> throw AssemblyError("not should have been replaced in the Ast by ==0")
|
||||||
|
else -> throw AssemblyError("invalid prefix operator")
|
||||||
|
}
|
||||||
|
assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// First assign the value to the target then apply the operator in place on the target.
|
// First assign the value to the target then apply the operator in place on the target.
|
||||||
// This saves a temporary variable
|
// This saves a temporary variable
|
||||||
translateNormalAssignment(
|
translateNormalAssignment(
|
||||||
@ -294,6 +334,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
"not" -> throw AssemblyError("not should have been replaced in the Ast by ==0")
|
"not" -> throw AssemblyError("not should have been replaced in the Ast by ==0")
|
||||||
else -> throw AssemblyError("invalid prefix operator")
|
else -> throw AssemblyError("invalid prefix operator")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// use a temporary variable
|
// use a temporary variable
|
||||||
val tempvar = if(value.type in ByteDatatypes) "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_W1"
|
val tempvar = if(value.type in ByteDatatypes) "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_W1"
|
||||||
@ -3419,6 +3460,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
DataType.BYTE -> {
|
DataType.BYTE -> {
|
||||||
when (target.kind) {
|
when (target.kind) {
|
||||||
TargetStorageKind.VARIABLE -> {
|
TargetStorageKind.VARIABLE -> {
|
||||||
|
if(asmgen.isTargetCpu(CpuType.CPU65c02))
|
||||||
|
asmgen.out("""
|
||||||
|
lda ${target.asmVarname}
|
||||||
|
eor #255
|
||||||
|
ina
|
||||||
|
sta ${target.asmVarname}""")
|
||||||
|
else
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #0
|
lda #0
|
||||||
sec
|
sec
|
||||||
@ -3432,7 +3480,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.out(" eor #255 | ina")
|
asmgen.out(" eor #255 | ina")
|
||||||
else
|
else
|
||||||
asmgen.out(" eor #255 | clc | adc #1")
|
asmgen.out(" eor #255 | clc | adc #1")
|
||||||
|
|
||||||
}
|
}
|
||||||
RegisterOrPair.X -> asmgen.out(" txa | eor #255 | tax | inx")
|
RegisterOrPair.X -> asmgen.out(" txa | eor #255 | tax | inx")
|
||||||
RegisterOrPair.Y -> asmgen.out(" tya | eor #255 | tay | iny")
|
RegisterOrPair.Y -> asmgen.out(" tya | eor #255 | tay | iny")
|
||||||
|
@ -13,13 +13,14 @@
|
|||||||
; SCREEN MODE LIST:
|
; SCREEN MODE LIST:
|
||||||
; mode 0 = reset back to default text mode
|
; mode 0 = reset back to default text mode
|
||||||
; mode 1 = bitmap 320 x 240 monochrome
|
; mode 1 = bitmap 320 x 240 monochrome
|
||||||
; mode 2 = bitmap 320 x 240 x 4c (TODO not yet implemented)
|
; mode 2 = bitmap 320 x 240 x 4c (not yet implemented: just use 256c, there's enough vram for that)
|
||||||
; mode 3 = bitmap 320 x 240 x 16c (TODO not yet implemented)
|
; mode 3 = bitmap 320 x 240 x 16c (not yet implemented: just use 256c, there's enough vram for that)
|
||||||
; mode 4 = bitmap 320 x 240 x 256c (like SCREEN $80 but using this api instead of kernal)
|
; mode 4 = bitmap 320 x 240 x 256c (like SCREEN $80 but using this api instead of kernal)
|
||||||
; mode 5 = bitmap 640 x 480 monochrome
|
; mode 5 = bitmap 640 x 480 monochrome
|
||||||
; mode 6 = bitmap 640 x 480 x 4c
|
; mode 6 = bitmap 640 x 480 x 4c
|
||||||
; higher color dephts in highres are not supported due to lack of VRAM
|
; higher color dephts in highres are not supported due to lack of VRAM
|
||||||
|
|
||||||
|
; TODO remove the phx/plx pairs in non-stack compiler version
|
||||||
|
|
||||||
gfx2 {
|
gfx2 {
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ gfx2 {
|
|||||||
height = 240
|
height = 240
|
||||||
bpp = 1
|
bpp = 1
|
||||||
}
|
}
|
||||||
; TODO modes 2, 3 not yet implemented
|
; TODO modes 2, 3
|
||||||
4 -> {
|
4 -> {
|
||||||
; lores 256c
|
; lores 256c
|
||||||
cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1
|
cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1
|
||||||
@ -109,7 +110,7 @@ gfx2 {
|
|||||||
repeat 240/2/8
|
repeat 240/2/8
|
||||||
cs_innerloop640()
|
cs_innerloop640()
|
||||||
}
|
}
|
||||||
; TODO mode 2, 3
|
; TODO modes 2, 3
|
||||||
4 -> {
|
4 -> {
|
||||||
; lores 256c
|
; lores 256c
|
||||||
repeat 240/2
|
repeat 240/2
|
||||||
@ -239,8 +240,7 @@ _done
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
6 -> {
|
6 -> {
|
||||||
; highres 4c
|
; highres 4c ....also mostly usable for mode 2, lores 4c?
|
||||||
; TODO also mostly usable for lores 4c?
|
|
||||||
color &= 3
|
color &= 3
|
||||||
ubyte[4] colorbits
|
ubyte[4] colorbits
|
||||||
ubyte ii
|
ubyte ii
|
||||||
@ -594,7 +594,7 @@ _done
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
; TODO mode 2,3
|
; TODO modes 2, 3
|
||||||
4 -> {
|
4 -> {
|
||||||
; lores 256c
|
; lores 256c
|
||||||
void addr_mul_24_for_lores_256c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
|
void addr_mul_24_for_lores_256c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
|
||||||
@ -646,8 +646,7 @@ _done
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
6 -> {
|
6 -> {
|
||||||
; highres 4c
|
; highres 4c ....also mostly usable for mode 2, 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
|
||||||
@ -701,7 +700,7 @@ _done
|
|||||||
+
|
+
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
; TODO mode 2 and 3
|
; TODO modes 2, 3
|
||||||
4 -> {
|
4 -> {
|
||||||
; lores 256c
|
; lores 256c
|
||||||
void addr_mul_24_for_lores_256c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
|
void addr_mul_24_for_lores_256c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
|
||||||
@ -875,19 +874,18 @@ skip:
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub position(uword @zp x, uword y) {
|
sub position(uword @zp x, uword y) {
|
||||||
ubyte bank
|
|
||||||
when active_mode {
|
when active_mode {
|
||||||
1 -> {
|
1 -> {
|
||||||
; lores monochrome
|
; lores monochrome
|
||||||
cx16.r0 = y*(320/8) + x/8
|
cx16.r0 = y*(320/8) + x/8
|
||||||
cx16.vaddr(0, cx16.r0, 0, 1)
|
cx16.vaddr(0, cx16.r0, 0, 1)
|
||||||
}
|
}
|
||||||
; TODO modes 2,3
|
; TODO modes 2, 3
|
||||||
4 -> {
|
4 -> {
|
||||||
; lores 256c
|
; lores 256c
|
||||||
void addr_mul_24_for_lores_256c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
|
void addr_mul_24_for_lores_256c(y, x) ; 24 bits result is in r0 and r1L (highest byte)
|
||||||
bank = lsb(cx16.r1)
|
cx16.r2L = cx16.r1L
|
||||||
cx16.vaddr(bank, cx16.r0, 0, 1)
|
cx16.vaddr(cx16.r2L, cx16.r0, 0, 1)
|
||||||
}
|
}
|
||||||
5 -> {
|
5 -> {
|
||||||
; highres monochrome
|
; highres monochrome
|
||||||
@ -897,24 +895,16 @@ skip:
|
|||||||
6 -> {
|
6 -> {
|
||||||
; highres 4c
|
; highres 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)
|
||||||
bank = lsb(cx16.r1)
|
cx16.r2L = cx16.r1L
|
||||||
cx16.vaddr(bank, cx16.r0, 0, 1)
|
cx16.vaddr(cx16.r2L, cx16.r0, 0, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub position2(uword @zp x, uword y, bool also_port_1) {
|
sub position2(uword @zp x, uword y, bool also_port_1) {
|
||||||
position(x, y)
|
position(x, y)
|
||||||
if also_port_1 {
|
if also_port_1
|
||||||
when active_mode {
|
cx16.vaddr_clone(0)
|
||||||
1, 5 -> cx16.vaddr(0, cx16.r0, 1, 1)
|
|
||||||
; TODO modes 2, 3
|
|
||||||
4, 6 -> {
|
|
||||||
ubyte bank = lsb(cx16.r1)
|
|
||||||
cx16.vaddr(bank, cx16.r0, 1, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline asmsub next_pixel(ubyte color @A) {
|
inline asmsub next_pixel(ubyte color @A) {
|
||||||
@ -986,48 +976,96 @@ skip:
|
|||||||
sub text(uword @zp x, uword y, ubyte color, uword sctextptr) {
|
sub text(uword @zp x, uword y, ubyte color, uword sctextptr) {
|
||||||
; -- Write some text at the given pixel position. The text string must be in screencode encoding (not petscii!).
|
; -- Write some text at the given pixel position. The text string must be in screencode encoding (not petscii!).
|
||||||
; You must also have called text_charset() first to select and prepare the character set to use.
|
; You must also have called text_charset() first to select and prepare the character set to use.
|
||||||
; NOTE: in monochrome (1bpp) screen modes, x position is currently constrained to multiples of 8 ! TODO allow per-pixel horizontal positioning
|
|
||||||
; TODO draw whole horizontal spans using vera auto increment if possible, instead of per-character columns
|
|
||||||
uword chardataptr
|
uword chardataptr
|
||||||
|
ubyte[8] @shared char_bitmap_bytes_left
|
||||||
|
ubyte[8] @shared char_bitmap_bytes_right
|
||||||
|
|
||||||
when active_mode {
|
when active_mode {
|
||||||
1, 5 -> {
|
1, 5 -> {
|
||||||
; monochrome mode, either resolution
|
; monochrome mode, either resolution
|
||||||
cx16.r2 = 40
|
cx16.r3 = sctextptr
|
||||||
if active_mode==5
|
while @(cx16.r3) {
|
||||||
cx16.r2 = 80
|
chardataptr = charset_addr + @(cx16.r3) * $0008
|
||||||
while @(sctextptr) {
|
; copy the character bitmap into RAM
|
||||||
chardataptr = charset_addr + (@(sctextptr) as uword)*8
|
cx16.vaddr_autoincr(charset_bank, chardataptr, 0, 1)
|
||||||
cx16.vaddr(charset_bank, chardataptr, 1, 1)
|
|
||||||
position(x,y)
|
|
||||||
%asm {{
|
%asm {{
|
||||||
lda cx16.VERA_ADDR_H
|
; pre-shift the bits
|
||||||
and #%111 ; don't auto-increment, we have to do that manually because of the ora
|
phx ; TODO remove in non-stack version
|
||||||
sta cx16.VERA_ADDR_H
|
lda text.x
|
||||||
lda color
|
and #7
|
||||||
sta P8ZP_SCRATCH_B1
|
sta P8ZP_SCRATCH_B1
|
||||||
ldy #8
|
ldy #0
|
||||||
- lda P8ZP_SCRATCH_B1
|
- lda cx16.VERA_DATA0
|
||||||
bne + ; white color, plot normally
|
stz P8ZP_SCRATCH_REG
|
||||||
lda cx16.VERA_DATA1
|
ldx P8ZP_SCRATCH_B1
|
||||||
eor #255 ; black color, keep only the other pixels
|
cpx #0
|
||||||
and cx16.VERA_DATA0
|
beq +
|
||||||
bra ++
|
- lsr a
|
||||||
+ lda cx16.VERA_DATA0
|
ror P8ZP_SCRATCH_REG
|
||||||
|
dex
|
||||||
|
bne -
|
||||||
|
+ sta char_bitmap_bytes_left,y
|
||||||
|
lda P8ZP_SCRATCH_REG
|
||||||
|
sta char_bitmap_bytes_right,y
|
||||||
|
iny
|
||||||
|
cpy #8
|
||||||
|
bne --
|
||||||
|
plx ; TODO remove in non-stack version
|
||||||
|
}}
|
||||||
|
; left part of shifted char
|
||||||
|
position2(x, y, true)
|
||||||
|
set_autoincrs_mode1_or_5()
|
||||||
|
if color {
|
||||||
|
%asm {{
|
||||||
|
ldy #0
|
||||||
|
- lda char_bitmap_bytes_left,y
|
||||||
ora cx16.VERA_DATA1
|
ora cx16.VERA_DATA1
|
||||||
+ sta cx16.VERA_DATA0
|
sta cx16.VERA_DATA0
|
||||||
lda cx16.VERA_ADDR_L
|
iny
|
||||||
clc
|
cpy #8
|
||||||
adc cx16.r2
|
|
||||||
sta cx16.VERA_ADDR_L
|
|
||||||
bcc +
|
|
||||||
inc cx16.VERA_ADDR_M
|
|
||||||
+ inc x
|
|
||||||
bne +
|
|
||||||
inc x+1
|
|
||||||
+ dey
|
|
||||||
bne -
|
bne -
|
||||||
}}
|
}}
|
||||||
sctextptr++
|
} else {
|
||||||
|
%asm {{
|
||||||
|
ldy #0
|
||||||
|
- lda char_bitmap_bytes_left,y
|
||||||
|
eor #255
|
||||||
|
and cx16.VERA_DATA1
|
||||||
|
sta cx16.VERA_DATA0
|
||||||
|
iny
|
||||||
|
cpy #8
|
||||||
|
bne -
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
; right part of shifted char
|
||||||
|
if lsb(x) & 7 {
|
||||||
|
position2(x+8, y, true)
|
||||||
|
set_autoincrs_mode1_or_5()
|
||||||
|
if color {
|
||||||
|
%asm {{
|
||||||
|
ldy #0
|
||||||
|
- lda char_bitmap_bytes_right,y
|
||||||
|
ora cx16.VERA_DATA1
|
||||||
|
sta cx16.VERA_DATA0
|
||||||
|
iny
|
||||||
|
cpy #8
|
||||||
|
bne -
|
||||||
|
}}
|
||||||
|
} else {
|
||||||
|
%asm {{
|
||||||
|
ldy #0
|
||||||
|
- lda char_bitmap_bytes_right,y
|
||||||
|
eor #255
|
||||||
|
and cx16.VERA_DATA1
|
||||||
|
sta cx16.VERA_DATA0
|
||||||
|
iny
|
||||||
|
cpy #8
|
||||||
|
bne -
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cx16.r3++
|
||||||
|
x += 8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
4 -> {
|
4 -> {
|
||||||
@ -1061,30 +1099,80 @@ skip:
|
|||||||
; hires 4c
|
; hires 4c
|
||||||
; we're going to use a few cx16 registers to make sure every variable is in zeropage in the inner loop.
|
; we're going to use a few cx16 registers to make sure every variable is in zeropage in the inner loop.
|
||||||
cx16.r11L = color
|
cx16.r11L = color
|
||||||
cx16.r8 = y
|
|
||||||
while @(sctextptr) {
|
while @(sctextptr) {
|
||||||
chardataptr = charset_addr + (@(sctextptr) as uword)*8
|
chardataptr = charset_addr + (@(sctextptr) as uword)*8
|
||||||
cx16.vaddr(charset_bank, chardataptr, 1, true) ; for reading the chardata from Vera data channel 1
|
cx16.vaddr(charset_bank, chardataptr, 1, true) ; for reading the chardata from Vera data channel 1
|
||||||
|
position(x, y) ; only calculated once, we update vera address in the loop instead
|
||||||
|
cx16.VERA_ADDR_H &= $0f ; no auto increment
|
||||||
repeat 8 {
|
repeat 8 {
|
||||||
; TODO rewrite this inner loop partly in assembly:
|
cx16.r10L = cx16.VERA_DATA1 ; get the next 8 horizontal character bits
|
||||||
; requires expanding the charbits to 2-bits per pixel (based on color)
|
|
||||||
; also it's way more efficient to draw whole horizontal spans instead of per-character
|
|
||||||
cx16.r9L = cx16.VERA_DATA1 ; get the next 8 horizontal character bits
|
|
||||||
cx16.r7 = x
|
cx16.r7 = x
|
||||||
repeat 8 {
|
repeat 8 {
|
||||||
cx16.r9L <<= 1
|
cx16.r10L <<= 1
|
||||||
if_cs
|
if_cs {
|
||||||
plot(cx16.r7, cx16.r8, cx16.r11L)
|
cx16.r2L = cx16.r7L & 3 ; xbits
|
||||||
cx16.r7++
|
when cx16.r11L & 3 {
|
||||||
|
1 -> cx16.r12L = gfx2.plot.shiftedleft_4c_1[cx16.r2L]
|
||||||
|
2 -> cx16.r12L = gfx2.plot.shiftedleft_4c_2[cx16.r2L]
|
||||||
|
3 -> cx16.r12L = gfx2.plot.shiftedleft_4c_3[cx16.r2L]
|
||||||
|
else -> cx16.r12L = 0
|
||||||
}
|
}
|
||||||
cx16.r8++
|
cx16.VERA_DATA0 = cx16.VERA_DATA0 & gfx2.plot.mask4c[cx16.r2L] | cx16.r12L
|
||||||
|
}
|
||||||
|
cx16.r7++
|
||||||
|
if (cx16.r7 & 3) == 0 {
|
||||||
|
; increment the pixel address by one
|
||||||
|
%asm {{
|
||||||
|
stz cx16.VERA_CTRL
|
||||||
|
clc
|
||||||
|
lda cx16.VERA_ADDR_L
|
||||||
|
adc #1
|
||||||
|
sta cx16.VERA_ADDR_L
|
||||||
|
lda cx16.VERA_ADDR_M
|
||||||
|
adc #0
|
||||||
|
sta cx16.VERA_ADDR_M
|
||||||
|
lda cx16.VERA_ADDR_H
|
||||||
|
adc #0
|
||||||
|
sta cx16.VERA_ADDR_H
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
; increment pixel address to the next line
|
||||||
|
%asm {{
|
||||||
|
stz cx16.VERA_CTRL
|
||||||
|
clc
|
||||||
|
lda cx16.VERA_ADDR_L
|
||||||
|
adc #(640-8)/4
|
||||||
|
sta cx16.VERA_ADDR_L
|
||||||
|
lda cx16.VERA_ADDR_M
|
||||||
|
adc #0
|
||||||
|
sta cx16.VERA_ADDR_M
|
||||||
|
lda cx16.VERA_ADDR_H
|
||||||
|
adc #0
|
||||||
|
sta cx16.VERA_ADDR_H
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
x+=8
|
x+=8
|
||||||
cx16.r8-=8
|
|
||||||
sctextptr++
|
sctextptr++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub set_autoincrs_mode1_or_5() {
|
||||||
|
; set autoincrements to go to next pixel row (40 or 80 increment)
|
||||||
|
if active_mode==1 {
|
||||||
|
cx16.VERA_CTRL = 0
|
||||||
|
cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & $0f | (11<<4)
|
||||||
|
cx16.VERA_CTRL = 1
|
||||||
|
cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & $0f | (11<<4)
|
||||||
|
} else {
|
||||||
|
cx16.VERA_CTRL = 0
|
||||||
|
cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & $0f | (12<<4)
|
||||||
|
cx16.VERA_CTRL = 1
|
||||||
|
cx16.VERA_ADDR_H = cx16.VERA_ADDR_H & $0f | (12<<4)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub cs_innerloop640() clobbers(Y) {
|
asmsub cs_innerloop640() clobbers(Y) {
|
||||||
|
@ -554,6 +554,25 @@ asmsub vaddr(ubyte bank @A, uword address @R0, ubyte addrsel @R1, byte autoIncrO
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asmsub vaddr_clone(ubyte port @A) clobbers (A,X,Y) {
|
||||||
|
; -- clones Vera addresses from the given source port to the other one.
|
||||||
|
; leaves CTRL on the destination port.
|
||||||
|
%asm {{
|
||||||
|
sta VERA_CTRL
|
||||||
|
ldx VERA_ADDR_L
|
||||||
|
ldy VERA_ADDR_H
|
||||||
|
phy
|
||||||
|
ldy VERA_ADDR_M
|
||||||
|
eor #1
|
||||||
|
sta VERA_CTRL
|
||||||
|
stx VERA_ADDR_L
|
||||||
|
sty VERA_ADDR_M
|
||||||
|
ply
|
||||||
|
sty VERA_ADDR_H
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
asmsub vaddr_autoincr(ubyte bank @A, uword address @R0, ubyte addrsel @R1, uword autoIncrAmount @R2) clobbers(A,Y) {
|
asmsub vaddr_autoincr(ubyte bank @A, uword address @R0, ubyte addrsel @R1, uword autoIncrAmount @R2) clobbers(A,Y) {
|
||||||
; -- setup the VERA's data address register 0 or 1
|
; -- setup the VERA's data address register 0 or 1
|
||||||
; including setting up optional auto increment amount.
|
; including setting up optional auto increment amount.
|
||||||
|
@ -324,7 +324,8 @@ This way you can set the second character on the second row from the top like th
|
|||||||
An uword variable can be used in limited scenarios as a 'pointer' to a byte in memory at a specific,
|
An uword variable can be used in limited scenarios as a 'pointer' to a byte in memory at a specific,
|
||||||
dynamic, location. You can use array indexing on a pointer variable to use it as a byte array at
|
dynamic, location. You can use array indexing on a pointer variable to use it as a byte array at
|
||||||
a dynamic location in memory: currently this is equivalent to directly referencing the bytes in
|
a dynamic location in memory: currently this is equivalent to directly referencing the bytes in
|
||||||
memory at the given index. See also :ref:`pointervars_programming`
|
memory at the given index. In contrast to a real array variable, the index value can be the size of a word.
|
||||||
|
See also :ref:`pointervars_programming`
|
||||||
|
|
||||||
**LSB/MSB split word arrays:**
|
**LSB/MSB split word arrays:**
|
||||||
For (u)word arrays, you can make the compiler layout the array in memory as two separate arrays,
|
For (u)word arrays, you can make the compiler layout the array in memory as two separate arrays,
|
||||||
@ -445,7 +446,7 @@ without defining a memory mapped location, you can do so by enclosing the addres
|
|||||||
|
|
||||||
This is the official syntax to 'dereference a pointer' as it is often named in other languages.
|
This is the official syntax to 'dereference a pointer' as it is often named in other languages.
|
||||||
You can actually also use the array indexing notation for this. It will be silently converted into
|
You can actually also use the array indexing notation for this. It will be silently converted into
|
||||||
the direct memory access expression as explained above. Note that this also means that unlike regular arrays,
|
the direct memory access expression as explained above. Note that unlike regular arrays,
|
||||||
the index is not limited to an ubyte value. You can use a full uword to index a pointer variable like this::
|
the index is not limited to an ubyte value. You can use a full uword to index a pointer variable like this::
|
||||||
|
|
||||||
pointervar[999] = 0 ; set memory byte to zero at location pointervar + 999.
|
pointervar[999] = 0 ; set memory byte to zero at location pointervar + 999.
|
||||||
|
@ -414,7 +414,8 @@ directly access the memory. Enclose a numeric expression or literal with ``@(...
|
|||||||
@($d020) = 0 ; set the c64 screen border to black ("poke 53280,0")
|
@($d020) = 0 ; set the c64 screen border to black ("poke 53280,0")
|
||||||
@(vic+$20) = 6 ; a dynamic expression to 'calculate' the address
|
@(vic+$20) = 6 ; a dynamic expression to 'calculate' the address
|
||||||
|
|
||||||
The array indexing notation on a uword 'pointer variable' is syntactic sugar for such a direct memory access expression::
|
The array indexing notation on a uword 'pointer variable' is syntactic sugar for such a direct memory access expression,
|
||||||
|
and the index value can be larger than a byte in this case::
|
||||||
|
|
||||||
pointervar[999] = 0 ; equivalent to @(pointervar+999) = 0
|
pointervar[999] = 0 ; equivalent to @(pointervar+999) = 0
|
||||||
|
|
||||||
@ -466,7 +467,7 @@ Syntax is familiar with brackets: ``arrayvar[x]`` ::
|
|||||||
|
|
||||||
Note: you can also use array indexing on a 'pointer variable', which is basically an uword variable
|
Note: you can also use array indexing on a 'pointer variable', which is basically an uword variable
|
||||||
containing a memory address. Currently this is equivalent to directly referencing the bytes in
|
containing a memory address. Currently this is equivalent to directly referencing the bytes in
|
||||||
memory at the given index. See :ref:`pointervars`
|
memory at the given index (and allows index values of word size). See :ref:`pointervars`
|
||||||
|
|
||||||
String
|
String
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
- IR: reduce the number of branch instructions (gradually), replace with CMP(I) + status branch instruction
|
- IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction
|
||||||
|
- IR: reduce amount of CMP/CMPI after instructions that set the status bits correctly (LOADs? INC? etc), but only after setting the status bits is verified!
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
@ -32,7 +33,6 @@ Compiler:
|
|||||||
- ir: the @split arrays are currently also split in _lsb/_msb arrays in the IR, and operations take multiple (byte) instructions that may lead to verbose and slow operation and machine code generation down the line.
|
- ir: the @split arrays are currently also split in _lsb/_msb arrays in the IR, and operations take multiple (byte) instructions that may lead to verbose and slow operation and machine code generation down the line.
|
||||||
- ir: for expressions with array indexes that occur multiple times, can we avoid loading them into new virtualregs everytime and just reuse a single virtualreg as indexer? (simple form of common subexpression elimination)
|
- ir: for expressions with array indexes that occur multiple times, can we avoid loading them into new virtualregs everytime and just reuse a single virtualreg as indexer? (simple form of common subexpression elimination)
|
||||||
- PtAst/IR: more complex common subexpression eliminations
|
- PtAst/IR: more complex common subexpression eliminations
|
||||||
- can we get rid of pieces of asmgen.AssignmentAsmGen by just reusing the AugmentableAssignment ? generated code should not suffer
|
|
||||||
- [problematic due to using 64tass:] better support for building library programs, where unused .proc shouldn't be deleted from the assembly?
|
- [problematic due to using 64tass:] better support for building library programs, where unused .proc shouldn't be deleted from the assembly?
|
||||||
Perhaps replace all uses of .proc/.pend/.endproc by .block/.bend will fix that with a compiler flag?
|
Perhaps replace all uses of .proc/.pend/.endproc by .block/.bend will fix that with a compiler flag?
|
||||||
But all library code written in asm uses .proc already..... (textual search/replace when writing the actual asm?)
|
But all library code written in asm uses .proc already..... (textual search/replace when writing the actual asm?)
|
||||||
@ -46,8 +46,6 @@ Libraries:
|
|||||||
- fix the problems in atari target, and flesh out its libraries.
|
- fix the problems in atari target, and flesh out its libraries.
|
||||||
- c128 target: make syslib more complete (missing kernal routines)?
|
- c128 target: make syslib more complete (missing kernal routines)?
|
||||||
- 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?
|
|
||||||
- actually implement modes 3 and perhaps even 2 to gfx2 (lores 16 color and 4 color)
|
|
||||||
|
|
||||||
|
|
||||||
Optimizations:
|
Optimizations:
|
||||||
@ -64,15 +62,8 @@ STRUCTS again?
|
|||||||
What if we were to re-introduce Structs in prog8? Some thoughts:
|
What if we were to re-introduce Structs in prog8? Some thoughts:
|
||||||
|
|
||||||
- can contain only numeric types (byte,word,float) - no nested structs, no reference types (strings, arrays) inside structs
|
- can contain only numeric types (byte,word,float) - no nested structs, no reference types (strings, arrays) inside structs
|
||||||
- is just some syntactic sugar for a scoped set of variables -> ast transform to do exactly this before codegen. Codegen doesn't know about struct.
|
- only as a reference type (uword pointer). This removes a lot of the problems related to introducing a variable length value type.
|
||||||
- no arrays of struct -- because too slow on 6502 to access those, rather use struct of arrays instead.
|
- arrays of struct is just an array of uword pointers. Can even be @split?
|
||||||
can we make this a compiler/codegen only issue? i.e. syntax is just as if it was an array of structs?
|
- need to introduce typed pointer datatype in prog8
|
||||||
or make it explicit in the syntax so that it is clear what the memory layout of it is.
|
- str is then syntactic sugar for pointer to character/byte?
|
||||||
- ability to assign struct variable to another? this is slow but can be quite handy sometimes.
|
- arrays are then syntactic sugar for pointer to byte/word/float?
|
||||||
however how to handle this in a function that gets the struct passed as reference? Don't allow it there? (there's no pointer dereferencing concept in prog8)
|
|
||||||
- ability to be passed as argument to a function (by reference)?
|
|
||||||
however there is no typed pointer in prog8 at the moment so this can't be implemented in a meaningful way yet,
|
|
||||||
because there is no way to reference it as the struct type again. (current ast gets the by-reference parameter
|
|
||||||
type replaced by uword)
|
|
||||||
So-- maybe don't replace the parameter type in the ast? Should fix that for str and array types as well then
|
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ widget {
|
|||||||
const ubyte height = 11
|
const ubyte height = 11
|
||||||
widget.highlightedrect(x+widget.window_close_icon.width, y, width-64, height, true, active)
|
widget.highlightedrect(x+widget.window_close_icon.width, y, width-64, height, true, active)
|
||||||
gfx2.plot(x+widget.window_close_icon.width, y+height-1, 1) ; correct bottom left corner
|
gfx2.plot(x+widget.window_close_icon.width, y+height-1, 1) ; correct bottom left corner
|
||||||
gfx2.text(x+32, y+1, 1, titlestr)
|
gfx2.text(x+26, y+1, 1, titlestr)
|
||||||
widget.window_close_icon(x, y, active)
|
widget.window_close_icon(x, y, active)
|
||||||
widget.window_order_icon(x+width-22, y, active)
|
widget.window_order_icon(x+width-22, y, active)
|
||||||
widget.window_flipsize_icon(x+width-44, y, active)
|
widget.window_flipsize_icon(x+width-44, y, active)
|
||||||
|
@ -5,4 +5,4 @@ org.gradle.daemon=true
|
|||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
javaVersion=11
|
javaVersion=11
|
||||||
kotlinVersion=1.9.0
|
kotlinVersion=1.9.0
|
||||||
version=9.2-SNAPSHOT
|
version=9.2
|
||||||
|
Loading…
Reference in New Issue
Block a user