X16: Updated to the newest hardware design

This commit is contained in:
Karol Stasiak 2020-05-01 15:19:25 +02:00
parent 655edc35ff
commit 4b5d290d6c
12 changed files with 540 additions and 183 deletions

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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

66
examples/x16/joydemo.mfk Normal file
View File

@ -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
]

View File

@ -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

196
include/x16/vera_7_or_8.mfk Normal file
View File

@ -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

132
include/x16/vera_9.mfk Normal file
View File

@ -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

View File

@ -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

View File

@ -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)
}

View File

@ -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

15
include/x16_mouse.mfk Normal file
View File

@ -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
}