Begun design and implementation of kernel VERA interface

This commit is contained in:
Kyle Cardoza 2024-03-28 19:49:21 -04:00
parent 15bdde96ad
commit 5032212b94
6 changed files with 411 additions and 94 deletions

View File

@ -22,7 +22,7 @@ clean:
@$(CC) -c $(CFLAGS) -o $@ $<
%.o: %.s
@echo "Assembling $@)..."
@echo "Assembling $@..."
@$(AS) $(ASFLAGS) -o $@ $<
%.d: %.c

View File

@ -6,18 +6,54 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
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);

View File

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

View File

@ -1,85 +0,0 @@
//*****************************************************************************
// Sentinel 65X Kernel
//
// src/drivers/vera.c
//*****************************************************************************
#include <stdint.h>
#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;
}

311
src/drivers/vera.s Normal file
View File

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

51
src/drivers/vera2.c Normal file
View File

@ -0,0 +1,51 @@
//*****************************************************************************
// Sentinel 65X Kernel
//
// src/drivers/vera2.c
//*****************************************************************************
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#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);
}