1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-06-11 15:29:34 +00:00

Support sizeof on arrays. Preliminary Commander X16 support.

This commit is contained in:
Karol Stasiak 2019-09-14 03:34:32 +02:00
parent 6c4dc81c1b
commit 1d445ecdd1
9 changed files with 276 additions and 4 deletions

View File

@ -2,12 +2,16 @@
## Current version
* `sizeof` now supports arrays.
* Added `-R` option for specifying extra commandline parameters for emulators.
* Added full 16-bit multiplication.
* Added preliminary support for EasyFlash.
* Added preliminary support for Commander X16.
* Allowed defining custom output padding byte value.
* Allowed passing non-decimal numbers to the `-D` option.

View File

@ -99,4 +99,7 @@ The compiler emits COM files.
* `dos_com` a COM file for DOS on IBM PC. (very experimental)
* `x16_experimental` Commander X16; very experimental,
as both the target configuration *and* the device itself are in their experimental phases.
The primary and most tested platform is Commodore 64.

View File

@ -84,7 +84,7 @@ See [the ROM vs RAM guide](../api/rom-vs-ram.md) for more information.
* `WIDESCREEN` 1 if the horizontal screen resolution, ignoring borders, is greater than 256, 0 otherwise
* `CBM` 1 if the target is an 8-bit Commodore computer, 0 otherwise
* `CBM` 1 if the target is an 8-bit Commodore computer (or a compatible one), 0 otherwise
* `CBM_64_COMPAT` 1 if the target is an 8-bit Commodore computer compatible with Commodore 64, 0 otherwise

View File

@ -4,7 +4,7 @@
* [Hello world](crossplatform/hello_world.mfk) (C64/C16/PET/VIC-20/PET/Atari/Apple II/BBC Micro/ZX Spectrum/PC-88/Armstrad CPC/MSX) simple text output
* [Fizzbuzz](crossplatform/fizzbuzz.mfk) (C64/C16/PET/VIC-20/PET/Atari/Apple II/BBC Micro/ZX Spectrum/PC-88/Armstrad CPC/MSX) everyone's favourite programming task
* [Fizzbuzz](crossplatform/fizzbuzz.mfk) (C64/C16/PET/VIC-20/PET/Atari/Apple II/BBC Micro/ZX Spectrum/PC-88/Armstrad CPC/MSX/X16) everyone's favourite programming task
* [Fizzbuzz 2](crossplatform/fizzbuzz2.mfk) (C64/C16/PET/VIC-20/PET/Atari/Apple II/BBC Micro/ZX Spectrum/PC-88/Armstrad CPC/MSX) an alternative, more extensible implemententation of fizzbuzz
@ -61,3 +61,9 @@ how to create a program made of multiple files loaded on demand
* [Encoding test](msx/encoding_test.mfk) text encoding test; displays three lines of text in three different languages,
no more one of which will display correctly depending on the default font of your computer.
# Commander X16 examples
* [Palette](x16/palette.mfk) displays the default 256-colour palette.
* [Balls](x16/palette.mfk) 16 sprites using 240 colours.

92
examples/x16/balls.mfk Normal file
View File

@ -0,0 +1,92 @@
// the emulator supports only 16 sprites:
const byte SPRITE_COUNT = 16
array(vera_sprite_data) sprites[SPRITE_COUNT]
array(sbyte) vx[SPRITE_COUNT]
array(sbyte) vy[SPRITE_COUNT]
import random
void main () {
pointer.vera_sprite_data p
byte i,j
word x,y
init_rand_seed()
// make balls striped
for i,0,parallelto,$1f {
for j,1,parallelto,$f {
sprite_bitmap[nonet(j<<5) + i] *= j
}
}
for i,0,paralleluntil,SPRITE_COUNT {
p = sprites[i].pointer
// bitmap is at $10000:
p->address = $800
p->x.lo = rand()
p->x.hi = rand() & 1
p->y = rand()
// no collision, above all layers, no flipping
p->ctrl0 = $c
// 32×32 pixels, different palette offsets
p->ctrl1 = $a0 | (i & $f)
vx[i] = 1 - (rand() & 2)
vy[i] = 1 - (rand() & 2)
}
vera_upload_large($10000, sprite_bitmap.addr, sizeof(sprite_bitmap))
vera_upload_large($40800, sprites.addr, sizeof(sprites))
// enable sprites:
vera_poke($40020, 1)
while true {
for i,0,paralleluntil,SPRITE_COUNT {
p = sprites[i].pointer
x = p->x
y = p->y
x += vx[i]
y += vy[i]
p->x = x
p->y = y
if x == 0 { vx[i] = 1 }
if x >= 640-32 { vx[i] = 0-1 }
if y == 0 { vy[i] = 1 }
if y >= 480-32 { vy[i] = 0-1 }
}
vera_upload_large($40800, sprites.addr, sizeof(sprites))
}
}
array sprite_bitmap = [
$00,$00,$00,$00,$00,$00,$11,$11,$11,$11,$00,$00,$00,$00,$00,$00,
$00,$00,$00,$00,$01,$11,$11,$11,$11,$11,$11,$10,$00,$00,$00,$00,
$00,$00,$00,$01,$11,$11,$11,$11,$11,$11,$11,$11,$10,$00,$00,$00,
$00,$00,$00,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$00,$00,$00,
$00,$00,$01,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$10,$00,$00,
$00,$00,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$00,$00,
$00,$01,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$10,$00,
$00,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$00,
$00,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$00,
$01,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$10,
$01,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$10,
$01,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$10,
$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,
$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,
$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,
$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,
$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,
$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,
$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,
$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,
$01,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$10,
$01,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$10,
$01,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$10,
$00,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$00,
$00,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$00,
$00,$01,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$10,$00,
$00,$00,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$00,$00,
$00,$00,$01,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$10,$00,$00,
$00,$00,$00,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$00,$00,$00,
$00,$00,$00,$01,$11,$11,$11,$11,$11,$11,$11,$11,$10,$00,$00,$00,
$00,$00,$00,$00,$01,$11,$11,$11,$11,$11,$11,$10,$00,$00,$00,$00,
$00,$00,$00,$00,$00,$00,$11,$11,$11,$11,$00,$00,$00,$00,$00,$00
]

24
examples/x16/palette.mfk Normal file
View File

@ -0,0 +1,24 @@
void main() {
word i
byte hn, ln
// 256-colour text mode for layer 0
vera_poke($40000, $21)
// 8×8 tiles, 64×64 tile map
vera_poke($40001, $35)
// 2× zoom in
vera_poke($40041, $40)
vera_poke($40042, $40)
i = 0
while i < $2000 {
vera_poke(i, $A0)
if i.lo & $7f < 64 {
ln = lo(i>>1) & $1f
hn = lo(i>>2) & $e0
vera_poke(i+1, hn | ln)
} else {
vera_poke(i+1, 0)
}
i += 2
}
while true {}
}

View File

@ -0,0 +1,40 @@
; Commander X16
; VERY EXPERIMENTAL
; The device's haven't been completed yet, so this platform configuration may not run on the final device
; Use only for goofing around plz
[compilation]
arch=cmos
encoding=petscii
screen_encoding=petscr
modules=loader_0801,c64_kernal,x16_hardware,c64_panic,stdlib
[allocation]
; list of free zp pointer locations is the same as C64
zp_pointers=$FB,$FD,$43,$45,$47,$4B,$F7,$F9,$9E,$9B,$3D
segments=default,himem0
default_code_segment=default
segment_default_start=$80D
segment_default_codeend=$9eff
segment_default_datastart=after_code
segment_default_end=$9eff
segment_himem0_start=$c000
segment_himem0_codeend=$dfff
segment_himem0_datastart=after_code
segment_himem0_end=$dfff
[define]
CBM=1
WIDESCREEN=1
KEYBOARD=1
JOYSTICKS=0
HAS_BITMAP_MODE=1
[output]
style=single
format=startaddr,allocated
extension=prg
labels=vice

103
include/x16_hardware.mfk Normal file
View File

@ -0,0 +1,103 @@
// TODO: bankswitching
volatile byte vera_addr_hi @ $9f20
volatile byte vera_addr_mi @ $9f21
volatile byte vera_addr_lo @ $9f22
volatile byte vera_data1 @ $9f23
volatile byte vera_data2 @ $9f24
volatile byte vera_ctrl @ $9f25
volatile byte vera_ien @ $9f26
volatile byte vera_isr @ $9f27
struct vera_layer_setup {
byte ctrl0
byte ctrl1
word map_base
word tile_base
word hscroll
word vscroll
}
asm void set_vera_layer_internal(pointer.vera_layer_setup ax, byte y) {
sta __reg
stx __reg+1
stz vera_ctrl
lda $14
sta vera_addr_hi
stz vera_addr_mi
sty vera_addr_lo
ldy #0
__set_layer_internal_loop:
lda (__reg),y
sta vera_data1
iny
cpy #sizeof(vera_layer_setup)
bne __set_layer_internal_loop
? rts
}
asm void set_vera_layer0(pointer.vera_layer_setup ax) {
? ldy #0
? jmp set_vera_layer_internal
}
asm void set_vera_layer1(pointer.vera_layer_setup ax) {
? ldy #0
? jmp set_vera_layer_internal
}
inline void vera_poke(int24 address, byte value) {
vera_addr_lo = address.b0
vera_addr_mi = address.b1
vera_addr_hi = address.b2
vera_ctrl = 0
vera_data1 = value
}
inline void vera_fill(int24 address, byte value, word size) {
word i
vera_addr_lo = address.b0
vera_addr_mi = address.b1
vera_addr_hi = address.b2 | $10
vera_ctrl = 0
for i,0,paralleluntil,size {
vera_data1 = value
}
}
void vera_upload_large(int24 address, pointer source, word size) {
word i
vera_ctrl = 0
vera_addr_lo = address.b0
vera_addr_mi = address.b1
vera_addr_hi = address.b2 | $10
for i,0,paralleluntil,size {
vera_data1 = source[i]
}
}
inline void vera_upload(int24 address, pointer source, byte size) {
byte i
vera_ctrl = 0
vera_addr_lo = address.b0
vera_addr_mi = address.b1
vera_addr_hi = address.b2 | $10
asm {
? ldy #0
__vera_upload_loop:
? lda (__reg),y
? sta vera_data1
? iny
? cpy size
? bne __vera_upload_loop
}
}
struct vera_sprite_data {
word address
word x
word y
byte ctrl0
byte ctrl1
}

View File

@ -599,8 +599,8 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
case Some(thing) => thing match {
case t: Type => t.size
case v: Variable => v.typ.size
case a: InitializedArray => a.elementType.size * a.contents.length
case a: UninitializedArray => a.sizeInBytes
case a: MfArray => a.sizeInBytes
case ConstantThing(_, MemoryAddressConstant(a: MfArray), _) => a.sizeInBytes
case x =>
log.error("Invalid parameter for expr: " + name)
1