1
0
mirror of https://github.com/KarolS/millfork.git synced 2026-04-22 00:17:03 +00:00

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
+3 -2
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
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
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
+4 -154
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
+27 -17
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)
}
+30
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
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
}