diff --git a/docs/lang/preprocessor.md b/docs/lang/preprocessor.md index 91359840..ba2f0cc8 100644 --- a/docs/lang/preprocessor.md +++ b/docs/lang/preprocessor.md @@ -124,7 +124,7 @@ These features are used to identify the target machine in multiplatform programs `COMMANDER_X16`, `CPM`, `GAMEBOY`, `IBM_PC`, `MSX`, `NEC_PC_88`, `NES`, `ZX_SPECTRUM` – 1 if the target is the machine in question, 0 otherwise -* `VERA_VERSION` – on Commander X16, the version of the VERA chip: `7` for 0.7, `8` for 0.8 +* `VERA_VERSION` – on Commander X16, the version of the VERA chip: `7` for 0.7, `8` for 0.8, `9` for 0.9 ### Built-in preprocessor functions and operators diff --git a/docs/stdlib/x16.md b/docs/stdlib/x16.md index a1596ea1..3279cc26 100644 --- a/docs/stdlib/x16.md +++ b/docs/stdlib/x16.md @@ -3,7 +3,8 @@ # Commander X16-oriented modules **WARNING!** Commander X16 is not yet a finalised design. -Therefore, both the device itself and the modules for its support may change at any moment. +Therefore, both the device itself and the modules for its support may change at any moment. +The X16-oriented modules may be out of date and not support the current design of the device. ## x16_kernal @@ -11,6 +12,11 @@ The `x16_kernal` module is imported automatically on the X16 target. Currently, it automatically imports the [`c64_kernal` module](./c64.md). +#### `void mouse_config(byte register(a) enable, byte register(x) scale)` + +Configures the mouse pointer. +`enable` should be `1` to enable, `0` to disable and `$ff` to enable without reconfiguration. +`scale` should be `1` on 640×480 screens, `2` on 320×240 screens, and `0` to keep the current scale. ## x16_hardware @@ -43,7 +49,7 @@ Copies `size` bytes from the RAM at address `source` into the VERA memory space #### `struct vera_layer_setup` -Hardware register values for a video layer: +Hardware register values for a video layer. For VERA 0.7 and 0.8: byte ctrl0 byte ctrl1 @@ -51,14 +57,32 @@ Hardware register values for a video layer: word tile_base word hscroll word vscroll + +For VERA 0.9: + + byte config + byte map_base + byte tile_base + word hscroll + word vscroll #### `void set_vera_layer1(pointer.vera_layer_setup)` -Sets up the layer 1. +Sets up the layer 1. VERA 0.7 and 0.8 only. +On VERA 0.9, use `vera_layer0` directly. #### `void set_vera_layer2(pointer.vera_layer_setup)` -Sets up the layer 2. +Sets up the layer 2. VERA 0.7 and 0.8 only. +On VERA 0.9, use `vera_layer1` directly. + +#### `vera_layer_setup vera_layer0` + +Direct access to registers for the layer 0. VERA 0.9 only. + +#### `vera_layer_setup vera_layer1` + +Direct access to registers for the layer 1. VERA 0.9 only. #### `struct vera_sprite_data` @@ -70,15 +94,33 @@ Hardware register values for a sprite: byte ctrl0 byte ctrl1 -#### `const int24 VERA_COMPOSER_CTRL` +#### `void vera_upload_sprite(byte sprite_id, pointer.vera_sprite_data source)` + +Uploads sprite data for given sprite id. + #### `const int24 VERA_PALETTE` -#### `const int24 VERA_LAYER_1` -#### `const int24 VERA_LAYER_2` -#### `const int24 VERA_SPRITE_CTRL` #### `const int24 VERA_SPRITES` Various addresses in the VERA memory space. +#### `const int24 VERA_COMPOSER_CTRL` +#### `const int24 VERA_LAYER_1` +#### `const int24 VERA_LAYER_2` +#### `const int24 VERA_SPRITE_CTRL` + +Various addresses in the VERA memory space. VERA 0.7 and 0.8 only. + +#### `void vera_reset()` + +Resets the VERA. + +#### `void vera_set_sprites_enable(bool enabled)` + +Enables/disables sprites. + +#### `void set_border(byte color)` + +Changes the color of the border. ## x16_joy @@ -119,6 +161,10 @@ Variable | SNES controller | NES controller | Keyboard (joy 1 only) `input_b` is an alias for `input_btn`. Single-button games should use `input_btn` for compatibility. + +#### `x16_joy_type joy_type` + +The type of the last read joystick. One of `joy_none`, `joy_nes`, `joy_snes`, `joy_keyboard`. ## x16_joy1_default module @@ -126,3 +172,12 @@ Defines the joystick in port 1 as the default joystick. #### `alias read_joy = read_joy1` +## x16_mouse + +The `x16_mouse` module implements a mouse driver compatible with the `mouse` module. + +Before using this, you may want to call `mouse_config` from the `x16_kernal` module. + +#### `void read_mouse()` + +Reads the state of the mouse. diff --git a/examples/README.md b/examples/README.md index f27de6c2..5a07c334 100644 --- a/examples/README.md +++ b/examples/README.md @@ -94,3 +94,5 @@ no more one of which will display correctly depending on the default font of you * [Palette](x16/palette.mfk) – displays the default 256-colour palette. * [Balls](x16/balls.mfk) – 16 sprites using 240 colours. + +* [Joy demo](x16/joydemo.mfk) – simple joystick demo. diff --git a/examples/x16/balls.mfk b/examples/x16/balls.mfk index b439cd01..612baa41 100644 --- a/examples/x16/balls.mfk +++ b/examples/x16/balls.mfk @@ -35,7 +35,7 @@ void main () { vera_upload_large($10000, sprite_bitmap.addr, sizeof(sprite_bitmap)) vera_upload_large(VERA_SPRITES, sprites.addr, sizeof(sprites)) // enable sprites: - vera_poke(VERA_SPRITE_CTRL, 1) + vera_set_sprites_enable(true) while true { for i,0,paralleluntil,SPRITE_COUNT { p = sprites[i].pointer diff --git a/examples/x16/joydemo.mfk b/examples/x16/joydemo.mfk new file mode 100644 index 00000000..b96ae20c --- /dev/null +++ b/examples/x16/joydemo.mfk @@ -0,0 +1,66 @@ +import x16_kernal +import x16_hardware +import x16_joy1_default + +vera_sprite_data sprite + +void main() { + + sprite.address = $800 + sprite.x = 100 + sprite.y = 100 + // no collision, above all layers, no flipping + sprite.ctrl0 = $c + // 32×32 pixels + sprite.ctrl1 = $a0 + + vera_upload_sprite(0, sprite.pointer) + vera_upload_large($10000, sprite_bitmap.addr, sizeof(sprite_bitmap)) + vera_set_sprites_enable(true) + while true { + read_joy() + sprite.x += input_dx + sprite.y += input_dy + if input_start != 0 { + sprite.ctrl1 = (sprite.ctrl1 & $f0) | ($f & (sprite.ctrl1 + 1)) + } + vera_upload_sprite(0, sprite.pointer) + //vera_upload_large(VERA_SPRITES, sprite.addr, sizeof(sprite)) + } +} + + +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 +] diff --git a/include/platform/x16_experimental.ini b/include/platform/x16_experimental.ini index 918241dc..fbcaa910 100644 --- a/include/platform/x16_experimental.ini +++ b/include/platform/x16_experimental.ini @@ -35,11 +35,12 @@ segment_himem_ff_bank=$ff CBM=1 COMMANDER_X16=1 WIDESCREEN=1 +TALLSCREEN=1 KEYBOARD=1 JOYSTICKS=2 HAS_BITMAP_MODE=1 -; Use VERA 0.8, as this is what the newest version of the emulator implements: -VERA_VERSION=8 +; Use VERA 0.9, as this is what the newest version of the emulator implements: +VERA_VERSION=9 [output] style=single diff --git a/include/x16/vera_7_or_8.mfk b/include/x16/vera_7_or_8.mfk new file mode 100644 index 00000000..389d2f37 --- /dev/null +++ b/include/x16/vera_7_or_8.mfk @@ -0,0 +1,196 @@ + +#if VERA_VERSION == 7 + +const int24 VERA_COMPOSER_CTRL = $40040 +const int24 VERA_PALETTE = $40200 +const int24 VERA_LAYER_1 = $40000 +const int24 VERA_LAYER_2 = $40010 +const int24 VERA_SPRITE_CTRL = $40020 +const int24 VERA_SPRITES = $40800 + +volatile byte vera_addr_hi @ $9f20 +volatile byte vera_addr_mi @ $9f21 +volatile byte vera_addr_lo @ $9f22 + +#elseif VERA_VERSION == 8 + +const int24 VERA_COMPOSER_CTRL = $F0000 +const int24 VERA_PALETTE = $F1000 +const int24 VERA_LAYER_1 = $F2000 +const int24 VERA_LAYER_2 = $F3000 +const int24 VERA_SPRITE_CTRL = $F4000 +const int24 VERA_SPRITES = $F5000 + +volatile byte vera_addr_hi @ $9f22 +volatile byte vera_addr_mi @ $9f21 +volatile byte vera_addr_lo @ $9f20 +volatile int24 vera_addr @ $9f20 + +#else +#error Unsupported VERA_VERSION +#endif + +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 +#if VERA_VERSION == 7 + lda $14 + sta vera_addr_hi + stz vera_addr_mi + sty vera_addr_lo +#elseif VERA_VERSION == 8 + lda $1F + sta vera_addr_hi + sty vera_addr_mi + stz vera_addr_lo +#else +#error Unsupported VERA_VERSION +#endif + 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_layer1(pointer.vera_layer_setup ax) { +#if VERA_VERSION == 7 + ? ldy #0 +#elseif VERA_VERSION == 8 + ? ldy #$20 +#else +#error Unsupported VERA_VERSION +#endif + ? jmp set_vera_layer_internal +} + +asm void set_vera_layer2(pointer.vera_layer_setup ax) { +#if VERA_VERSION == 7 + ? ldy #$10 +#elseif VERA_VERSION == 8 + ? ldy #$30 +#else +#error Unsupported VERA_VERSION +#endif + ? 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 byte vera_peek(int24 address) { + vera_addr_lo = address.b0 + vera_addr_mi = address.b1 + vera_addr_hi = address.b2 + vera_ctrl = 0 + return vera_data1 +} + +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) { + 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 (source),y + ! sta vera_data1 + ? iny + ? cpy size + ? bne __vera_upload_loop + } +} + +inline void vera_reset() { + vera_ctrl = $80 + vera_ctrl = 0 +} + +inline void vera_set_sprites_enable(bool enabled) { + vera_ctrl = 0 + vera_ctrl = 0 +} + +struct vera_sprite_data { + word address + word x + word y + byte ctrl0 + byte ctrl1 +} + +void vera_upload_sprite(byte sprite_id, pointer.vera_sprite_data source) { + vera_ctrl = 0 + vera_addr_lo = sprite_id << 3 + vera_addr_mi = (sprite_id >> 5) | VERA_SPRITES.b1 + vera_addr_hi = VERA_SPRITES.b2 | $10 + asm { + ? ldy #7 + __vera_upload_sprite_loop: + ? lda (source),y + ! sta vera_data0 + ? iny + ? cpy #sizeof(vera_sprite_data) + ? bne __vera_upload_sprite_loop + } +} + +inline void vera_set_sprites_enable(bool enabled) { + vera_poke(VERA_SPRITE_CTRL, byte(enabled)) +} + +inline void vera_set_border(byte color) { + vera_poke(VERA_COMPOSER_CTRL + 3, color) +} + +alias set_border = vera_set_border diff --git a/include/x16/vera_9.mfk b/include/x16/vera_9.mfk new file mode 100644 index 00000000..c66e36b1 --- /dev/null +++ b/include/x16/vera_9.mfk @@ -0,0 +1,132 @@ + +#if VERA_VERSION != 9 +#error Unsupported VERA_VERSION +#endif + + +const int24 VERA_PALETTE = $1FA00 +const int24 VERA_SPRITES = $1FC00 + +volatile byte vera_addr_lo @ $9f20 +volatile byte vera_addr_mi @ $9f21 +volatile byte vera_addr_hi @ $9f22 +volatile int24 vera_addr @ $9f20 +volatile byte vera_data0 @ $9f23 +volatile byte vera_data1 @ $9f24 +volatile byte vera_ctrl @ $9f25 +volatile byte vera_ien @ $9f26 +volatile byte vera_isr @ $9f27 +volatile byte vera_irqline @ $9f28 +volatile byte vera_dc_video_hstart @ $9f29 +volatile byte vera_dc_hscale_hstop @ $9f29 +volatile byte vera_dc_vscale_vstart @ $9f2b +volatile byte vera_dc_border_vstop @ $9f2c + +struct vera_layer_setup { + byte config + byte map_base + byte tile_base + word hscroll + word vscroll +} + +volatile vera_layer_setup vera_layer0 @$9F2D +volatile vera_layer_setup vera_layer1 @$9F34 + + + +inline void vera_poke(int24 address, byte value) { + vera_ctrl = 0 + vera_addr = address + vera_data0 = value +} + +inline byte vera_peek(int24 address) { + vera_ctrl = 0 + vera_addr = address + return vera_data0 +} + +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_data0 = 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_data0 = source[i] + } +} + +inline void vera_upload(int24 address, pointer source, byte size) { + 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 (source),y + ! sta vera_data0 + ? iny + ? cpy size + ? bne __vera_upload_loop + } +} + +inline void vera_reset() { + vera_ctrl = $80 + vera_ctrl = 0 +} + +struct vera_sprite_data { + word address + word x + word y + byte ctrl0 + byte ctrl1 +} + +void vera_upload_sprite(byte sprite_id, pointer.vera_sprite_data source) { + vera_ctrl = 0 + vera_addr_lo = sprite_id << 3 + vera_addr_mi = (sprite_id >> 5) | VERA_SPRITES.b1 + vera_addr_hi = VERA_SPRITES.b2 | $10 + asm { + ? ldy #0 + __vera_upload_sprite_loop: + ? lda (source),y + ! sta vera_data0 + ? iny + ? cpy #sizeof(vera_sprite_data) + ? bne __vera_upload_sprite_loop + } +} + +inline void vera_set_sprites_enable(bool enabled) { + vera_ctrl = 0 + if enabled { + vera_dc_video_hstart |= $40 + } else { + vera_dc_video_hstart &= $ff ^ $40 + } +} + +inline void vera_set_border(byte color) { + vera_ctrl = 0 + vera_dc_border_vstop = color +} + +alias set_border = vera_set_border + diff --git a/include/x16_hardware.mfk b/include/x16_hardware.mfk index 4eec1dc2..9006630f 100644 --- a/include/x16_hardware.mfk +++ b/include/x16_hardware.mfk @@ -1,162 +1,12 @@ -#if VERA_VERSION == 7 - -const int24 VERA_COMPOSER_CTRL = $40040 -const int24 VERA_PALETTE = $40200 -const int24 VERA_LAYER_1 = $40000 -const int24 VERA_LAYER_2 = $40010 -const int24 VERA_SPRITE_CTRL = $40020 -const int24 VERA_SPRITES = $40800 - -volatile byte vera_addr_hi @ $9f20 -volatile byte vera_addr_mi @ $9f21 -volatile byte vera_addr_lo @ $9f22 - -#elseif VERA_VERSION == 8 - -const int24 VERA_COMPOSER_CTRL = $F0000 -const int24 VERA_PALETTE = $F1000 -const int24 VERA_LAYER_1 = $F2000 -const int24 VERA_LAYER_2 = $F3000 -const int24 VERA_SPRITE_CTRL = $F4000 -const int24 VERA_SPRITES = $F5000 - -volatile byte vera_addr_hi @ $9f22 -volatile byte vera_addr_mi @ $9f21 -volatile byte vera_addr_lo @ $9f20 -volatile int24 vera_addr @ $9f20 - +#if VERA_VERSION < 9 +import x16/vera_7_or_8 +#elseif VERA_VERSION == 9 +import x16/vera_9 #else #error Unsupported VERA_VERSION #endif -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 -#if VERA_VERSION == 7 - lda $14 - sta vera_addr_hi - stz vera_addr_mi - sty vera_addr_lo -#elseif VERA_VERSION == 8 - lda $1F - sta vera_addr_hi - sty vera_addr_mi - stz vera_addr_lo -#else -#error Unsupported VERA_VERSION -#endif - 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_layer1(pointer.vera_layer_setup ax) { -#if VERA_VERSION == 7 - ? ldy #0 -#elseif VERA_VERSION == 8 - ? ldy #$20 -#else -#error Unsupported VERA_VERSION -#endif - ? jmp set_vera_layer_internal -} - -asm void set_vera_layer2(pointer.vera_layer_setup ax) { -#if VERA_VERSION == 7 - ? ldy #$10 -#elseif VERA_VERSION == 8 - ? ldy #$30 -#else -#error Unsupported VERA_VERSION -#endif - ? 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 byte vera_peek(int24 address) { - vera_addr_lo = address.b0 - vera_addr_mi = address.b1 - vera_addr_hi = address.b2 - vera_ctrl = 0 - return vera_data1 -} - -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 (source),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 -} - inline asm void set_ram_bank(byte register(a) bank) { ! STA $9F61 ? RTS diff --git a/include/x16_joy.mfk b/include/x16_joy.mfk index 49ae1010..3292518c 100644 --- a/include/x16_joy.mfk +++ b/include/x16_joy.mfk @@ -1,3 +1,4 @@ +import joy void x16_reset_joy() { input_dx = 0 @@ -40,6 +41,15 @@ byte input_l // SNES:R byte input_r +enum x16_joy_type { + joy_nes = 0 + joy_keyboard = 1 + joy_snes = 15 + joy_none = 255 +} + +x16_joy_type joy_type + void read_joy1() { x16_reset_joy() read_also_joy1() @@ -48,26 +58,25 @@ void read_joy2() { x16_reset_joy() read_also_joy2() } -asm void read_also_joy1() { - JSR $FF06 - LDA $F1 - BNE __read_also_joy1_skip - LDA $EF - JSR x16_joy_byte0 - LDA $F0 - JSR x16_joy_byte1 -__read_also_joy1_skip: - RTS + +inline void read_also_joy1() { + __read_joy(0) } -asm void read_also_joy2() { - JSR $FF06 - LDA $F4 - BNE __read_also_joy2_skip - LDA $F2 +inline void read_also_joy2() { + __read_joy(1) +} + +asm void __read_joy(byte register(a) joy_id) { + JSR $FF53 // TODO: should we? + JSR $FF56 + STY joy_type + CPY #0 + BMI __read_joy_skip + PHX JSR x16_joy_byte0 - LDA $F3 + PLA JSR x16_joy_byte1 -__read_also_joy2_skip: +__read_joy_skip: RTS } @@ -86,4 +95,5 @@ void x16_joy_byte1(byte value) { if value & 32 == 0 { input_l += 1 } if value & 64 == 0 { input_x += 1 } if value & 128 == 0 { input_a += 1 } + joy_type = x16_joy_type(value & 15) } diff --git a/include/x16_kernal.mfk b/include/x16_kernal.mfk index cc44aa18..22193645 100644 --- a/include/x16_kernal.mfk +++ b/include/x16_kernal.mfk @@ -1,2 +1,32 @@ // Let's be lazy: import c64_kernal + +array(word) kernal_registers [16] @ 2 + +struct clock_date_time_t { + byte year + byte month + byte day + byte hour + byte minute + byte second + byte jiffies +} + +clock_date_time_t clock_date_time @ 2 + +asm void clock_set_date_time() @$FF4D extern + +asm void clock_get_date_time() @$FF50 extern + +asm void mouse_config(byte register(a) enable, byte register(x) scale) @$FF68 extern + +asm byte mouse_get(byte register(x) offset) @$FF6B extern + +asm void mouse_scan() @$FF71 extern + +asm byte joystick_get(byte register(a) joy_id) @$FF56 extern + +asm void joystick_scan() @$FF53 extern + + diff --git a/include/x16_mouse.mfk b/include/x16_mouse.mfk new file mode 100644 index 00000000..8daf2c2d --- /dev/null +++ b/include/x16_mouse.mfk @@ -0,0 +1,15 @@ +import x16_kernal +import mouse + +void read_mouse() { + byte btn + mouse_scan() + btn = mouse_get(0) + mouse_x = kernal_registers[0] + mouse_y = kernal_registers[1] + mouse_lbm = btn & 1 != 0 + mouse_rbm = btn & 2 != 0 +#if USE_MOUSE_MBM + mouse_mbm = btn & 4 != 0 +#endif +}