diff --git a/config/sdk-targets.mk b/config/sdk-targets.mk index 21c1ebb..2d25599 100644 --- a/config/sdk-targets.mk +++ b/config/sdk-targets.mk @@ -22,7 +22,7 @@ clean: @$(CC) -c $(CFLAGS) -o $@ $< %.o: %.s - @echo "Assembling $@)..." + @echo "Assembling $@..." @$(AS) $(ASFLAGS) -o $@ $< %.d: %.c diff --git a/include/drivers/vera.h b/include/drivers/vera.h index 29ede9c..3150e57 100644 --- a/include/drivers/vera.h +++ b/include/drivers/vera.h @@ -6,18 +6,54 @@ #pragma once +#include #include -void vera_init(void); +typedef enum { + ADDR_INCREMENT_0 = 0, + ADDR_INCREMENT_1 = 1, + ADDR_INCREMENT_2 = 2, + ADDR_INCREMENT_4 = 3, + ADDR_INCREMENT_8 = 4, + ADDR_INCREMENT_16 = 5, + ADDR_INCREMENT_32 = 6, + ADDR_INCREMENT_64 = 7, + ADDR_INCREMENT_128 = 8, + ADDR_INCREMENT_256 = 9, + ADDR_INCREMENT_512 = 10, + ADDR_INCREMENT_40 = 11, + ADDR_INCREMENT_80 = 12, + ADDR_INCREMENT_160 = 13, + ADDR_INCREMENT_320 = 14, + ADDR_INCREMENT_640 = 15 +} VeraAddressIncrement; -uint8_t vera_peek(uint32_t addr); +extern void vera_init(void); -uint16_t vera_peek16(uint32_t addr); +extern void vera_set_data0_address(uint32_t addr); -void vera_poke(uint32_t addr, uint8_t value); +extern void vera_set_data1_address(uint32_t addr); -void vera_poke16(uint32_t addr, uint16_t value); +extern uint8_t vera_peek_data0(void); -void _vera_set_bgcolor(uint8_t color); -#define vera_set_bgcolor(X) _vera_set_bgcolor((X)) -#define vera_set_bgcolour(X) _vera_set_bgcolor((X)) +extern uint8_t vera_peek_data1(void); + +extern void vera_poke_data0(uint8_t value); + +extern void vera_poke_data1(uint8_t value); + +extern void vera_set_addr0_auto_increment(VeraAddressIncrement value); + +extern void vera_set_addr1_auto_increment(VeraAddressIncrement value); + +extern void vera_set_addr0_decrement(bool state); + +extern void vera_set_addr1_decrement(bool state); + +uint8_t vera_read_byte(uint32_t addr); + +uint16_t vera_read_word(uint32_t addr); + +void vera_write_byte(uint32_t addr, uint8_t value); + +void vera_write_word(uint32_t addr, uint16_t value); diff --git a/include/macros.h b/include/macros.h index 5f1cd4f..a4bece1 100644 --- a/include/macros.h +++ b/include/macros.h @@ -3,6 +3,10 @@ #ifdef __CALYPSI_ASSEMBLER__ +#define short_a sep #0b00100000 + +#define long_a rep #0b00100000 + #ifdef __CALYPSI_CODE_MODEL_SMALL__ #define libcode code diff --git a/src/drivers/vera.c b/src/drivers/vera.c deleted file mode 100644 index d969289..0000000 --- a/src/drivers/vera.c +++ /dev/null @@ -1,85 +0,0 @@ -//***************************************************************************** -// Sentinel 65X Kernel -// -// src/drivers/vera.c -//***************************************************************************** - -#include - -#include "config.h" -#include "drivers/vera.h" - -typedef struct vera_s *VERA; - -struct vera_s { - uint8_t addr_x_l; - uint8_t addr_x_m; - uint8_t addr_x_h; - union { - uint8_t data[2]; - uint16_t data16; - }; - uint8_t ctrl; - uint8_t ien; - uint8_t isr; - union { - uint8_t irq_line_l; - uint8_t const scanline_l; - }; -}; - -VERA vera = (VERA)(0x00df00); - -void -vera_init(void) -{ - -} - -uint8_t -vera_peek(uint32_t addr) -{ - (void) addr; - - // Set addrsel to 0 - uint8_t asel = vera->ctrl; - vera->ctrl = asel & 0b11111110; - - // Set address - vera->addr_x_l = addr & 0x000000FF; - vera->addr_x_m = (addr & 0x0000FF00) >> 8; - - vera->addr_x_h = vera->addr_x_h & 0b11111110; - - vera->addr_x_h = vera->addr_x_h | (addr & ((uint32_t)(1) << 16)); - - return vera->data[0]; -} - -void -vera_poke(uint32_t addr, uint8_t value) -{ - (void) addr; - - // Set addrsel to 0 - uint8_t asel = vera->ctrl; - vera->ctrl = asel & 0b11111110; - - // Set address - vera->addr_x_l = addr & 0x000000FF; - vera->addr_x_m = (addr & 0x0000FF00) >> 8; - - vera->addr_x_h = vera->addr_x_h & 0b11111110; - - vera->addr_x_h = vera->addr_x_h | (addr & ((uint32_t)(1) << 16)); - - vera->data[0] = value; - return; -} - -void -_vera_set_bgcolor(uint8_t color) -{ - (void) color; - return; -} diff --git a/src/drivers/vera.s b/src/drivers/vera.s new file mode 100644 index 0000000..b5ee4e0 --- /dev/null +++ b/src/drivers/vera.s @@ -0,0 +1,311 @@ +;;***************************************************************************** +;; Sentinel 65X Kernel +;; +;; src/drivers/vera.s +;;***************************************************************************** + +#include "macros.h" + + .section code + + .public vera_init + .public vera_set_data0_address + .public vera_set_data1_address + .public vera_peek_data0 + .public vera_peek_data1 + .public vera_poke_data0 + .public vera_poke_data1 + .public vera_set_addr0_auto_increment + .public vera_set_addr1_auto_increment + .public vera_set_addr0_decrement + .public vera_set_addr1_decrement + + .extern _Dp + +vera_init: + rts + +; Set the data0 address. +; +; Arguments: +; _Dp[0-2]: 24-bit VERA address to read +; Return value: +; None +; +vera_set_data0_address: + phb + + short_a + + ; Set the data bank to 0 + lda #0 + pha + plb + + ; Set ADDRSEL to 0. + lda #0b00000001 + trb 0xDF05 + + ; Set the low byte of the address + lda _Dp+0 + sta 0xDF00 + + ; Set the mid byte of the address + lda _Dp+1 + sta 0xDF01 + + ; Set the high bit of the address + lda _Dp+2 + and #0b00000001 + + ; If the high bit in A is set, then branch + bne d0_high_bit_set + ; Else clear the lowest bit of ADDR0_H + lda #0b00000001 + trb 0xDF03 + ; And exit + bra d0_done + +d0_high_bit_set: + ; Set the lowest bit of ADDR0_H + lda #0b00000001 + tsb 0xDF03 + +d0_done: + long_a + + plb + rts + +; Set the data1 address. +; +; Arguments: +; _Dp[0-2]: 24-bit VERA address to read +; Return value: +; None +; +vera_set_data1_address: + phb + + short_a + + ; Set the data bank to 0 + lda #0 + pha + plb + + ; Set ADDRSEL to 1. + lda #0b00000001 + tsb 0xDF05 + + ; Set the low byte of the address + lda _Dp+0 + sta 0xDF00 + + ; Set the mid byte of the address + lda _Dp+1 + sta 0xDF01 + + ; Set the high bit of the address + lda _Dp+2 + and #0b00000001 + + ; If the high bit in A is set, then branch + bne d1_high_bit_set + ; Else clear the lowest bit of ADDR1_H + lda #0b00000001 + trb 0xDF03 + ; And exit + bra d1_done + +d1_high_bit_set: + ; Set the lowest bit of ADDR1_H + lda #0b00000001 + tsb 0xDF03 + +d1_done: + long_a + + plb + rts + +vera_peek_data0: + short_a + + lda 0x00DF03 + + long_a + rts + +vera_peek_data1: + short_a + + lda 0x00DF04 + + long_a + rts + +vera_poke_data0: + short_a + + sta 0x00DF03 + + long_a + rts + +vera_poke_data1: + short_a + + sta 0x00DF04 + + long_a + rts + + +; Set the data0 address auto-increment +; +; Arguments: +; A: Increment value (0-15) +; Return value: +; None +; +vera_set_addr0_auto_increment: + phb + short_a + pha + + ; Set the data bank to 0 + lda #0 + pha + plb + + ; Set ADDRSEL to 0. + lda #0b00000001 + trb 0xDF05 + + ; Clear the high four bits of ADDR0_H + lda #0b11110000 + trb 0xDF02 + + pla + asl a + asl a + asl a + asl a + tsb 0xDF02 + + long_a + rts + +; Set the data1 address auto-increment +; +; Arguments: +; A: Increment value (0-15) +; Return value: +; None +; +vera_set_addr1_auto_increment: + phb + short_a + pha + + ; Set the data bank to 0 + lda #0 + pha + plb + + ; Set ADDRSEL to 1. + lda #0b00000001 + tsb 0xDF05 + + ; Clear the high four bits of ADDR0_H + lda #0b11110000 + trb 0xDF02 + + pla + asl a + asl a + asl a + asl a + tsb 0xDF02 + + long_a + rts + + +; If the argument is non-zero, set DECR0, else clear it. +; +; Arguments: +; A: State (C boolean) +; Return value: +; None +; +vera_set_addr0_decrement: + phb + short_a + pha + + ; Set the data bank to 0 + lda #0 + pha + plb + + ; Set ADDRSEL to 0. + lda #0b00000001 + trb 0xDF05 + + pla + beq vera_set_addr0_decrement_false + +vera_set_addr0_decrement_true: + lda #0b00001000 + tsb 0xDF02 + bra vera_set_addr0_decrement_done + +vera_set_addr0_decrement_false: + lda #0b00001000 + trb 0xDF02 + +vera_set_addr0_decrement_done: + long_a + plb + rts + + +; If the argument is non-zero, set DECR1, else clear it. +; +; Arguments: +; A: State (C boolean) +; Return value: +; None +; +vera_set_addr1_decrement: + phb + short_a + pha + + ; Set the data bank to 0 + lda #0 + pha + plb + + ; Set ADDRSEL to 1. + lda #0b00000001 + tsb 0xDF05 + + pla + beq vera_set_addr1_decrement_false + +vera_set_addr1_decrement_true: + lda #0b00001000 + tsb 0xDF02 + bra vera_set_addr1_decrement_done + +vera_set_addr1_decrement_false: + lda #0b00001000 + trb 0xDF02 + +vera_set_addr1_decrement_done: + long_a + plb + rts diff --git a/src/drivers/vera2.c b/src/drivers/vera2.c new file mode 100644 index 0000000..44487a7 --- /dev/null +++ b/src/drivers/vera2.c @@ -0,0 +1,51 @@ +//***************************************************************************** +// Sentinel 65X Kernel +// +// src/drivers/vera2.c +//***************************************************************************** + +#include +#include +#include + +#include "config.h" +#include "drivers/vera.h" + +uint8_t +vera_read_byte(uint32_t addr) +{ + vera_set_data0_address(addr); + vera_set_addr0_auto_increment(ADDR_INCREMENT_0); + vera_set_addr0_decrement(false); + return vera_peek_data0(); +} + +uint16_t +vera_read_word(uint32_t addr) +{ + vera_set_data0_address(addr); + vera_set_addr0_auto_increment(ADDR_INCREMENT_1); + vera_set_addr0_decrement(false); + uint8_t data_low = vera_peek_data0(); + uint8_t data_high = vera_peek_data0(); + return (uint16_t)((data_high << 8) & data_low); +} + +void +vera_write_byte(uint32_t addr, uint8_t value) +{ + vera_set_data0_address(addr); + vera_set_addr0_auto_increment(ADDR_INCREMENT_0); + vera_set_addr0_decrement(false); + vera_poke_data0(value); +} + +void +vera_write_word(uint32_t addr, uint16_t value) +{ + vera_set_data0_address(addr); + vera_set_addr0_auto_increment(ADDR_INCREMENT_1); + vera_set_addr0_decrement(false); + vera_poke_data0((uint8_t)(value & 0x00FF)); + vera_poke_data0((uint8_t)(value & 0xFF00) >> 8); +}