Rewrite from scratch using 64tass.

This commit is contained in:
Kyle J Cardoza 2024-06-10 15:37:54 -04:00
parent edc645aee7
commit c61597ae46
31 changed files with 883 additions and 2517 deletions

View File

@ -1,5 +1,40 @@
# There is no need to edit this file. Make your changes in config/config.mk.
AS := 64tass
MP := minipro
include config/config.mk
include config/sdk-config.mk
include config/sdk-targets.mk
ASFLAGS := --nostart \
-I include \
-I src \
--long-branch \
--long-address \
--m65816 \
-Wno-wrap-pc \
-l kernel.list
MPFLAGS := -p SST39LF040@PLCC32
SOURCES := src/memory.s \
src/main.s \
src/boot.s \
src/irq.s \
src/vera.s
INCLUDES := $(wildcard include/*.i)
TARGET := sentinel65x-firmware-512k
.PHONY: all
all: $(TARGET).bin
@du -h $(TARGET).bin
$(TARGET).bin: $(SOURCES)
$(AS) $(ASFLAGS) -o $@ $^
.PHONY: flash
flash: $(TARGET).bin
$(MP) $(MPFLAGS) -w $<
.PHONY: clean
clean:
rm -f $(TARGET).bin
.PREFIXES:

View File

@ -1,3 +0,0 @@
# Sentinel 65X Kernel
This is the early skeleton of what will become the kernel in Sentinel 65X. It will provide the hardware and protocol drivers and core API used by the C library, as well as an assembly language kernel API.

View File

View File

@ -1,67 +0,0 @@
(define memories '(
(memory HighRAM
(address (#x010000 . #x01EFFF))
(section farcode)
(section fardata)
(section far)
(section cfar)
(section chuge)
(section data_init_table)
(section switch)
(section itiny)
(section inear)
(section ifar)
(section ihuge)
(type ram)
)
(memory HighBSS
(address (#x01F000 . #x01FFFF))
(section heap)
(section huge)
(section zhuge)
(section zfar)
(type ram)
)
(memory MidRAM
(address (#x00F000 . #x00FFFF))
(section code)
(section cnear)
(section reset)
(type ram)
)
(memory LowRAM
(address (#x00E000 . #x00EFFF))
(section znear)
(section near)
(type ram)
)
(memory IOSpace
(address (#x00DF00 . #x00DFFF))
(section (VERAIOPort #x00DF00))
)
(memory stack
(address (#x000100 . #x007FFF))
(section (stack #x00100))
)
(memory DirectPage
(address (#x000000 . #x0000FF))
(section
(registers #x000004)
(ztiny)
)
)
(block stack (size #x7F00)) ; machine stack size
(block heap (size #x0001))
(base-address _DirectPageStart DirectPage 0)
(base-address _NearBaseAddress LowRAM 0)
))

View File

@ -1,71 +0,0 @@
SHELL := bash
CC := cc65816
AS := as65816
AR := nlib
LD := ln65816
.SUFFIXES:
.SUFFIXES: .c .s .o .a
MEMORY_MAP := config/memory.scm
CFLAGS := --include-system=include/libc \
-I include \
--code-model=large \
--data-model=huge \
--64bit-doubles \
--strong-inline \
--force-switch jump-table
ASFLAGS := -I include \
--code-model=large \
--data-model=huge
ifeq ($(RELEASE), "true")
CFLAGS += -DNDEBUG \
-O2 \
--speed
else
CFLAGS += --debug \
-Wall \
-Wextra \
-Wpedantic \
-Werror \
-Wno-c11-extensions \
-Wno-gnu-binary-literal \
-Wno-gnu-conditional-omitted-operand \
-Wno-gnu-case-range \
-Wimplicit-fallthrough \
-Wno-gnu-folding-constant
ASFLAGS += --debug
endif
ifeq ($(ENABLE_RELEASE_BUILD), "true")
CFLAGS += -DRELEASE_BUILD
CFLAGS += -DNDEBUG
else
CFLAGS += -DDEBUG
endif
LIBS := build/libc.a
LDFLAGS := $(MEMORY_MAP) \
--rtattr cstartup=sentinel65x \
--list-file build.lst \
--verbose \
--output-format pgz
KERNEL_SRC_C := $(wildcard src/*.c) \
$(wildcard src/*/*.c) \
$(wildcard src/*/*/*.c) \
$(wildcard src/*/*/*/*.c) \
$(wildcard src/*/*/*/*/*.c)
KERNEL_SRC_S := $(wildcard src/*.s) \
$(wildcard src/*/*.s) \
$(wildcard src/*/*/*.s) \
$(wildcard src/*/*/*/*.s) \
$(wildcard src/*/*/*/*/*.s)
KERNEL_OBJ := $(KERNEL_SRC_C:.c=.o) \
$(KERNEL_SRC_S:.s=.o)
KERNEL_DEP := $(KERNEL_SRC_C:.c=.d)

View File

@ -1,37 +0,0 @@
.PHONY: all
all: build/kernel.pgz
.PHONY: clean
clean:
@find build -type f \( \
-name '*.pgz' -o \
-name '*.bin' -o \
-name '*.elf' -o \
-name '*.raw' -o \
-name '*.a' \
\) -delete
@find src -type f \( \
-name '*.o' -o \
-name '*.d' -o \
-name '$(TARGET)' \
\) -delete
@rm -f *.lst
%.o: %.c
@echo "Compiling $@..."
@$(CC) -c $(CFLAGS) -o $@ $<
%.o: %.s
@echo "Assembling $@..."
@$(AS) $(ASFLAGS) -o $@ $<
%.d: %.c
@echo "Generating dependencies for $<"
@printf '%s' "$(dir $@)" > $@
@$(CC) $(CFLAGS) --dependencies $< >> $@
build/kernel.pgz: $(KERNEL_OBJ)
@echo "Linking $@..."
@$(LD) $(LDFLAGS) -o $@ $^
-include $(KERNEL_DEP)

View File

@ -1,13 +0,0 @@
//*****************************************************************************
// Sentinel 65X Kernel
//
// include/config.h
//*****************************************************************************
#pragma once
#define far __far
#define near __near
#define interrupt_handler(X) __attribute__((interrupt((X))))

View File

@ -1,106 +0,0 @@
//*****************************************************************************
// Sentinel 65X Kernel
//
// include/drivers/vera.h
//*****************************************************************************
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "config.h"
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;
typedef enum {
VERA_DEPTH_1BPP,
VERA_DEPTH_2BPP,
VERA_DEPTH_4BPP,
VERA_DEPTH_8BPP
} VeraBitDepth;
typedef union vera_palette_entry_s {
struct {
uint8_t blue: 4;
uint8_t green: 4;
uint8_t red: 4;
uint8_t padding: 4;
};
uint8_t byte_value[2];
} VeraPaletteEntry;
typedef struct vera_palette_s {
union {
VeraPaletteEntry color[256];
VeraPaletteEntry colour[256];
};
} VeraPalette;
void vera_init(void);
extern void vera_reset(void);
extern void vera_set_data0_address(uint32_t addr);
extern void vera_set_data1_address(uint32_t addr);
extern uint8_t vera_peek_data0(void);
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);
extern void vera_set_addr0_incr1(uint32_t addr);
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);
void vera_read(void *dest, uint32_t src, size_t length);
void vera_write(uint32_t dest, void *src, size_t length);
void vera_memset(uint32_t addr, uint8_t value, size_t length);
VeraPaletteEntry vera_make_palette_entry(uint32_t rgb_value);
VeraPaletteEntry vera_get_palette_entry(uint8_t index);
void vera_set_palette_entry(uint8_t index, VeraPaletteEntry value);
void vera_palette_read(VeraPalette *dest);
void vera_palette_write(VeraPalette *src);

View File

@ -1,69 +0,0 @@
//*****************************************************************************
// Sentinel 65X Kernel
//
// include/drivers/vera_sprites.h
//*****************************************************************************
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "config.h"
#include "drivers/vera.h"
typedef enum {
SPRITE_ORDER_DISABLE,
SPRITE_ORDER_BOTTOM,
SPRITE_ORDER_MID,
SPRITE_ORDER_TOP
} VeraSpriteZOrder;
typedef enum {
SPRITE_SIZE_8,
SPRITE_SIZE_16,
SPRITE_SIZE_32,
SPRITE_SIZE_64,
} VeraSpriteSize;
void vera_sprite_set_bitmap_address(uint8_t index, uint32_t address);
uint32_t vera_sprite_get_bitmap_address(uint8_t index);
void vera_sprite_set_bit_depth(uint8_t index, VeraBitDepth depth);
VeraBitDepth vera_sprite_get_bit_depth(uint8_t index);
void vera_sprite_set_z_order(uint8_t index, VeraSpriteZOrder order);
VeraSpriteZOrder vera_sprite_get_z_order(uint8_t index);
void vera_sprite_set_x_position(uint8_t index, uint16_t position);
uint16_t vera_sprite_get_x_position(uint8_t index);
void vera_sprite_set_y_position(uint8_t index, uint16_t position);
uint16_t vera_sprite_get_y_position(uint8_t index);
void vera_sprite_set_h_flip(uint8_t index, bool state);
bool vera_sprite_get_h_flip(uint8_t index);
void vera_sprite_set_v_flip(uint8_t index, bool state);
bool vera_sprite_get_v_flip(uint8_t index);
void vera_sprite_set_width(uint8_t index, VeraSpriteSize size);
VeraSpriteSize vera_sprite_get_width(uint8_t index);
void vera_sprite_set_height(uint8_t index, VeraSpriteSize size);
VeraSpriteSize vera_sprite_get_height(uint8_t index);
void vera_sprite_set_palette_offset(uint8_t index, uint8_t value);
uint8_t vera_sprite_get_palette_offset(uint8_t index);

View File

@ -1,11 +0,0 @@
//*****************************************************************************
// Sentinel 65X Kernel
//
// include/interrupts.h
//*****************************************************************************
#pragma once
#include "config.h"
extern void interrupts_init(void);

View File

@ -1,106 +0,0 @@
#ifndef __MACROS_H
#define __MACROS_H
#ifdef __CALYPSI_ASSEMBLER__
#define short_a sep #0b00100000
#define long_a rep #0b00100000
#define short_i sep #0b00010000
#define long_i rep #0b00010000
#define short_reg sep #0b00110000
#define long_reg rep #0b00110000
int .macro f
php
long_reg
ldx ##\f
cop #\f
plp
.endm
#ifdef __CALYPSI_CODE_MODEL_SMALL__
#define libcode code
call .macro dest
jsr \dest
.endm
return .macro
rts
.endm
jump .macro dest
jmp \dest
.endm
#elif defined(__CALYPSI_CODE_MODEL_COMPACT__)
#define libcode compactcode
call .macro dest
jsr .kbank \dest
.endm
return .macro
rts
.endm
jump .macro dest
jmp .kbank \dest
.endm
#else
#define libcode farcode
call .macro dest
jsl \dest
.endm
return .macro
rtl
.endm
jump .macro dest
jmp long:\dest
.endm
#endif // __CALYPSI_CODE_MODEL_SMALL__
// ----------------------------------------------------------------------
//
// Define code and data model used. This is to add a bit of safety in
// case the way a file is assembled is combined with the wrong run-time.
//
// ----------------------------------------------------------------------
#if defined(__CALYPSI_DATA_MODEL_SMALL__)
.rtmodel dataModel,"small"
#elif defined (__CALYPSI_DATA_MODEL_MEDIUM__)
.rtmodel dataModel,"medium"
#elif defined(__CALYPSI_DATA_MODEL_LARGE__)
.rtmodel dataModel,"large"
#elif defined(__CALYPSI_DATA_MODEL_HUGE__)
.rtmodel dataModel,"huge"
#else
#pragma GCC error "unexpected data model"
#endif
#if defined(__CALYPSI_CODE_MODEL_SMALL__)
.rtmodel codeModel,"small"
#elif defined(__CALYPSI_CODE_MODEL_COMPACT__)
.rtmodel codeModel,"compact"
#elif defined(__CALYPSI_CODE_MODEL_LARGE__)
.rtmodel codeModel,"large"
#else
#pragma GCC error "unexpected code model"
#endif
#endif // __CALYPSI_ASSEMBLER__
#endif // __MACROS_H

7
include/sentinel65x.i Normal file
View File

@ -0,0 +1,7 @@
CPU_SPEED_HZ = 8000000
UART3_BAUD_RATE = 9600
UART3_TIMER_VALUE = (CPU_SPEED_HZ / (16 * UART3_BAUD_RATE) - 1)
.include "w65c816.i"
.include "w65c265s.i"
.include "vera.i"

View File

@ -1,9 +0,0 @@
//*****************************************************************************
// Sentinel 65X Kernel
//
// include/sys/types.h
//*****************************************************************************
#pragma once
typedef long ssize_t;

160
include/vera.i Normal file
View File

@ -0,0 +1,160 @@
AUTO_INC_NONE = $000000
AUTO_INC_1 = $100000
AUTO_INC_2 = $200000
AUTO_INC_4 = $300000
AUTO_INC_8 = $400000
AUTO_INC_16 = $500000
AUTO_INC_32 = $600000
AUTO_INC_64 = $700000
AUTO_INC_128 = $800000
AUTO_INC_256 = $900000
AUTO_INC_512 = $A00000
AUTO_INC_40 = $B00000
AUTO_INC_80 = $C00000
AUTO_INC_160 = $D00000
AUTO_INC_320 = $E00000
AUTO_INC_640 = $F00000
DISABLED = 0
ENABLED = 1
VERA_L_BPP1 = %00000000
VERA_L_BPP2 = %00000001
VERA_L_BPP4 = %00000010
VERA_L_BPP8 = %00000011
VERA_L_BITMAP = %00000100
VERA_L_T256C = %00001000
VERA_L_32W = %00000000
VERA_L_64W = %00010000
VERA_L_128W = %00100000
VERA_L_256W = %00110000
VERA_L_32H = %00000000
VERA_L_64H = %01000000
VERA_L_128H = %10000000
VERA_L_256H = %11000000
VERA_TILESIZE8x8 = %00000000
VERA_TILESIZE16x8 = %00000001
VERA_TILESIZE8x16 = %00000010
VERA_TILESIZE16x16 = %00000011
; The base address of the VERA chip
VERA_BASE = $00DF00
; Offsets (relative to VERA_BASE) for each VERA register
VERA_ADDRx_L = VERA_BASE + 00
VERA_ADDRx_M = VERA_BASE + 01
VERA_ADDRx_H = VERA_BASE + 02
; Accssible with ADDRSEL == 0
VERA_ADDR0_L = VERA_BASE + 00
VERA_ADDR0_M = VERA_BASE + 01
VERA_ADDR0_H = VERA_BASE + 02
; Accssible with ADDRSEL == 1
VERA_ADDR1_L = VERA_BASE + 00
VERA_ADDR1_M = VERA_BASE + 01
VERA_ADDR1_H = VERA_BASE + 02
VERA_DATA0 = VERA_BASE + $03
VERA_DATA1 = VERA_BASE + $04
VERA_CTRL = VERA_BASE + $05
VERA_IEN = VERA_BASE + $06
VERA_ISR = VERA_BASE + $06
VERA_IRQLINE_L = VERA_BASE + $07
VERA_SCANLINE_L = VERA_BASE + $08
; Accssible with DCSEL == 0
VERA_DC_VIDEO = VERA_BASE + $09
VERA_DC_HSCALE = VERA_BASE + $0A
VERA_DC_VSCALE = VERA_BASE + $0B
VERA_DC_BORDER = VERA_BASE + $0C
; Accssible with DCSEL == 1
VERA_DC_HSTART = VERA_BASE + $09
VERA_DC_HSTOP = VERA_BASE + $0A
VERA_DC_VSTART = VERA_BASE + $0B
VERA_DC_VSTOP = VERA_BASE + $0C
; Layer 0
VERA_L0_CONFIG = VERA_BASE + $0D
VERA_L0_MAPBASE = VERA_BASE + $0E
VERA_L0_TILEBASE = VERA_BASE + $0F
VERA_L0_HSCROLL_L = VERA_BASE + $10
VERA_L0_HSCROLL_H = VERA_BASE + $11
VERA_L0_VSCROLL_L = VERA_BASE + $12
VERA_L0_VSCROLL_H = VERA_BASE + $13
; Layer 1
VERA_L1_CONFIG = VERA_BASE + $14
VERA_L1_MAPBASE = VERA_BASE + $15
VERA_L1_TILEBASE = VERA_BASE + $16
VERA_L1_HSCROLL_L = VERA_BASE + $17
VERA_L1_HSCROLL_H = VERA_BASE + $18
VERA_L1_VSCROLL_L = VERA_BASE + $19
VERA_L1_VSCROLL_H = VERA_BASE + $1A
; Audio
VERA_AUDIO_CTRL = VERA_BASE + $1B
VERA_AUDIO_RATE = VERA_BASE + $1C
VERA_AUDIO_DATA = VERA_BASE + $1D
; SPI (Unused in prototype four!)
VERA_SPI_DATA = VERA_BASE + $1E
VERA_SPI_CTRL = VERA_BASE + $1F
; VRAM layout
VERA_PSG_BASE = $1F9C0
VERA_PALETTE_BASE = $1FA00
VERA_SPRITE_ATTR_BASE = $1FC00
; vpoke
; writes an immediate byte to a given register
vpoke .macro reg, value
php
rep #$20
.al
pha
sep #$20
.as
lda #\value
sta \reg
rep #$20
.al
pla
plp
.endmacro
; vera_address_set - sets the address registers to the passed in value
vera_address_set .macro addr
php
rep #$20
.al
pha
sep #$20
.as
lda #\addr & $ff
sta VERA_ADDRx_L
lda #(\addr >> 8) & $ff
sta VERA_ADDRx_M
lda #(\addr >> 16) & $ff
sta VERA_ADDRx_H
rep #$20
.al
pla
plp
.endmacro

78
include/w65c265s.i Normal file
View File

@ -0,0 +1,78 @@
PD0 = $00DF00
PD1 = $00DF01
PD2 = $00DF02
PD3 = $00DF03
PDD0 = $00DF04
PDD1 = $00DF05
PDD2 = $00DF06
PDD3 = $00DF07
PD4 = $00DF20
PD5 = $00DF21
PD6 = $00DF22
PD7 = $00DF23
PDD4 = $00DF24
PDD5 = $00DF25
PDD6 = $00DF26
PCS7 = $00DF27
BCR = $00DF40
SSCR = $00DF41
TCR = $00DF42
TER = $00DF43
TIFR = $00DF44
EIFR = $00DF45
TIER = $00DF46
EIER = $00DF47
UIFR = $00DF48
UIER = $00DF49
T0LL = $00DF50
T0LH = $00DF51
T1LL = $00DF52
T1LH = $00DF53
T2LL = $00DF54
T2LH = $00DF55
T3LL = $00DF56
T3LH = $00DF57
T4LL = $00DF58
T4LH = $00DF59
T5LL = $00DF5A
T5LH = $00DF5B
T6LL = $00DF5C
T6LH = $00DF5D
T7LL = $00DF5E
T7LH = $00DF5F
T0CL = $00DF60
T0CH = $00DF61
T1CL = $00DF62
T1CH = $00DF63
T2CL = $00DF64
T2CH = $00DF65
T3CL = $00DF66
T3CH = $00DF67
T4CL = $00DF68
T4CH = $00DF69
T5CL = $00DF6A
T5CH = $00DF6B
T6CL = $00DF6C
T6CH = $00DF6D
T7CL = $00DF6E
T7CH = $00DF6F
ACSR0 = $00DF70
ARTD0 = $00DF71
ACSR1 = $00DF72
ARTD1 = $00DF73
ACSR2 = $00DF74
ARTD2 = $00DF75
ACSR3 = $00DF76
ARTD3 = $00DF77
PIBFR = $00DF78
PIBER = $00DF79
PIR2 = $00DF7A
PIR3 = $00DF7B
PIR4 = $00DF7C
PIR5 = $00DF7D
PIR6 = $00DF7E
PIR7 = $00DF7F

24
include/w65c816.i Normal file
View File

@ -0,0 +1,24 @@
native_mode .macro
clc
xce
.endmacro
long_a .macro
rep #$20
.al
.endmacro
short_a .macro
sep #$20
.as
.endmacro
long_i .macro
rep #$10
.xl
.endmacro
short_i .macro
sep #$10
.xs
.endmacro

166
kernel.list Normal file
View File

@ -0,0 +1,166 @@
UART3_TIMER_VALUE= 51
VERA_L0_TILEBASE= 57103
CPU_SPEED_HZ = 8000000
TIER = $00df46
T3LL = $00df56
TCR = $00df42
T3LH = $00df57
T0LL = $00df50
T0LH = $00df51
AUTO_INC_320 = $e00000
SSCR = $00df41
UIER = $00df49
AUTO_INC_256 = $900000
AUTO_INC_128 = $800000
VERA_DC_VIDEO = 57097
VERA_DC_HSCALE = 57098
AUTO_INC_NONE = $000000
main = $c0ffc0
AUTO_INC_40 = $b00000
VERA_DC_VSCALE = 57099
VERA_CTRL = 57093
EIER = $00df47
T2CH = $00df65
T0CH = $00df61
T0CL = $00df60
VERA_L0_MAPBASE = 57102
AUTO_INC_2 = $200000
AUTO_INC_1 = $100000
VERA_AUDIO_DATA = 57117
VERA_TILESIZE8x8= $00
AUTO_INC_16 = $500000
VERA_SCANLINE_L = 57096
T4LH = $00df59
T4LL = $00df58
TER = $00df43
UIFR = $00df48
VERA_PSG_BASE = $1f9c0
VERA_ADDR1_L = 57088
PD7 = $00df23
PD6 = $00df22
VERA_DC_HSTOP = 57098
PD4 = $00df20
PD3 = $00df03
PD2 = $00df02
PD1 = $00df01
PD0 = $00df00
VERA_L1_CONFIG = 57108
AUTO_INC_64 = $700000
VERA_AUDIO_RATE = 57116
ACSR0 = $00df70
VERA_BASE = $00df00
ACSR2 = $00df74
ACSR3 = $00df76
T4CL = $00df68
T6CH = $00df6d
T4CH = $00df69
T6CL = $00df6c
VERA_DATA1 = 57092
VERA_L0_VSCROLL_H= 57107
VERA_L0_VSCROLL_L= 57106
VERA_IEN = 57094
PCS7 = $00df27
VERA_L_64W = $10
VERA_L_64H = $40
VERA_L1_TILEBASE= 57110
T7LH = $00df5f
AUTO_INC_80 = $c00000
PDD5 = $00df25
PDD6 = $00df26
PDD0 = $00df04
PDD1 = $00df05
PDD2 = $00df06
PDD3 = $00df07
w65c265s_init = $008008
VERA_L_128H = $80
VERA_DC_VSTART = 57099
VERA_L_BPP8 = $03
VERA_DATA0 = 57091
AUTO_INC_4 = $300000
AUTO_INC_8 = $400000
T7LL = $00df5e
VERA_L_32W = $00
VERA_L_128W = $20
PIBFR = $00df78
AUTO_INC_32 = $600000
VERA_L0_CONFIG = 57101
VERA_DC_BORDER = 57100
T7CH = $00df6f
AUTO_INC_160 = $d00000
vera_init = $c0ffee
T2LL = $00df54
TIFR = $00df44
T2LH = $00df55
T5CL = $00df6a
AUTO_INC_512 = $a00000
T5CH = $00df6b
T7CL = $00df6e
EIFR = $00df45
VERA_L_256H = $c0
VERA_L_256W = $30
PIR7 = $00df7f
PIR6 = $00df7e
PIR5 = $00df7d
PIR4 = $00df7c
PIR3 = $00df7b
PIR2 = $00df7a
VERA_L_T256C = $08
VERA_SPI_DATA = 57118
T2CL = $00df64
VERA_ADDR0_H = 57090
VERA_SPI_CTRL = 57119
VERA_PALETTE_BASE= $1fa00
VERA_ADDR0_M = 57089
VERA_ADDR0_L = 57088
VERA_L_BPP4 = $02
VERA_L_BPP1 = $00
VERA_L_BPP2 = $01
VERA_TILESIZE16x16= $03
AUTO_INC_640 = $f00000
T5LH = $00df5b
ENABLED = 1
T5LL = $00df5a
VERA_TILESIZE8x16= $02
VERA_ISR = 57094
irq_exit = $00810d
VERA_ADDR1_M = 57089
UART3_BAUD_RATE = 9600
ACSR1 = $00df72
VERA_DC_VSTOP = 57100
VERA_L_32H = $00
VERA_L_BITMAP = $04
VERA_IRQLINE_L = 57095
T6LL = $00df5c
PDD4 = $00df24
T3CL = $00df66
T3CH = $00df67
VERA_L1_MAPBASE = 57109
VERA_L0_HSCROLL_L= 57104
VERA_L0_HSCROLL_H= 57105
T6LH = $00df5d
T1CH = $00df63
T1CL = $00df62
VERA_ADDR1_H = 57090
VERA_ADDRx_H = 57090
PIBER = $00df79
VERA_ADDRx_M = 57089
VERA_ADDRx_L = 57088
VERA_L1_HSCROLL_H= 57112
T1LL = $00df52
VERA_L1_HSCROLL_L= 57111
nmi_handler = $00810c
empty_irq_handler= $008100
VERA_TILESIZE16x8= $01
VERA_AUDIO_CTRL = 57115
VERA_DC_HSTART = 57097
DISABLED = 0
ARTD2 = $00df75
ARTD3 = $00df77
ARTD0 = $00df71
ARTD1 = $00df73
T1LH = $00df53
VERA_SPRITE_ATTR_BASE= $1fc00
BCR = $00df40
PD5 = $00df21
VERA_L1_VSCROLL_L= 57113
VERA_L1_VSCROLL_H= 57114

40
src/boot.s Normal file
View File

@ -0,0 +1,40 @@
.section code
.section boot
.logical $008000
.null "WDC"
jml w65c265s_init
w65c265s_init .proc
; Disable standard interrupts
sei
.short_a
.long_i
; Set data bank to 0
lda #0
pha
plb
.databank 0
; Set direct page to $0000
pea $0000
pld
.dpage $0000
; Set stack to $001FF
ldx #$01FF
txs
; Enable all used chip select lines.
lda #%11110011
sta PCS7
; Jump to entry point.
jml main
.endproc
.endlogical
.endsection boot
.endsection code

View File

@ -1,143 +0,0 @@
;;; Startup variant, change attribute value if you make your own
.rtmodel cstartup,"sentinel65x"
.rtmodel version, "1"
.rtmodel core, "*"
.section stack
.section heap
.section data_init_table
.extern main, exit
.extern _Dp, _Vfp
.extern _DirectPageStart
#ifndef __CALYPSI_DATA_MODEL_SMALL__
.extern _NearBaseAddress
#endif
#include "macros.h"
;;; ***************************************************************************
;;;
;;; The reset vector. This uses the entry point label __program_root_section
;;; which by default is what the linker will pull in first.
;;;
;;; ***************************************************************************
.section reset
.pubweak __program_root_section
__program_root_section:
.word __program_start
;;; ***************************************************************************
;;;
;;; __program_start - actual start point of the program
;;;
;;; Set up CPU stack, initialize sections and call main().
;;; You can override this with your own routine, or tailor it as needed.
;;; The easiest way to make custom initialization is to provide your own
;;; __low_level_init which gets called after stacks have been initialized.
;;;
;;; ***************************************************************************
#ifdef __CALYPSI_CODE_MODEL_COMPACT__
.section code
#else
.section code, noreorder
#endif
.pubweak __program_start
__program_start:
clc
xce ; native 16-bit mode
rep #0x38 ; 16-bit registers, no decimal mode
ldx ##.sectionEnd stack
txs ; set stack
lda ##_DirectPageStart
tcd ; set direct page
#ifdef __CALYPSI_DATA_MODEL_SMALL__
lda ##0
#else
lda ##.word2 _NearBaseAddress
#endif
stz dp:.tiny(_Vfp+2)
xba ; A upper half = data bank
pha
plb ; pop 8 dummy
plb ; set data bank
#ifdef __CALYPSI_CODE_MODEL_COMPACT__
jmp long:_Trampoline_program_start
.section compactcode, noreorder
_Trampoline_program_start:
#define CODE compactcode
#else
#define CODE code
#endif
call __low_level_init
;;; **** Initialize data sections if needed.
.section CODE, noroot, noreorder
.pubweak __data_initialization_needed
.extern __initialize_sections
__data_initialization_needed:
lda ##.word2 (.sectionEnd data_init_table)
sta dp:.tiny(_Dp+6)
lda ##.word0 (.sectionEnd data_init_table)
sta dp:.tiny(_Dp+4)
lda ##.word2 (.sectionStart data_init_table)
sta dp:.tiny(_Dp+2)
lda ##.word0 (.sectionStart data_init_table)
sta dp:.tiny(_Dp+0)
call __initialize_sections
;;; **** Initialize streams if needed.
.section CODE, noroot, noreorder
.pubweak __call_initialize_global_streams
.extern __initialize_global_streams
__call_initialize_global_streams:
call __initialize_global_streams
;;; **** Initialize heap if needed.
.section CODE, noroot, noreorder
.pubweak __call_heap_initialize
.extern __heap_initialize, __default_heap
__call_heap_initialize:
#ifdef __CALYPSI_DATA_MODEL_SMALL__
lda ##.sectionSize heap
sta dp:.tiny(_Dp+2)
lda ##.sectionStart heap
sta dp:.tiny(_Dp+0)
lda ##__default_heap
#else
lda ##.word2 (.sectionStart heap)
sta dp:.tiny(_Dp+6)
lda ##.word0 (.sectionStart heap)
sta dp:.tiny(_Dp+4)
lda ##.word2 __default_heap
sta dp:.tiny(_Dp+2)
lda ##.word0 __default_heap
sta dp:.tiny(_Dp+0)
ldx ##.word2 (.sectionSize heap)
lda ##.word0 (.sectionSize heap)
#endif
call __heap_initialize
.section CODE, root, noreorder
lda ##0 ; argc = 0
call main
jump exit
;;; ***************************************************************************
;;;
;;; __low_level_init - custom low level initialization
;;;
;;; This default routine just returns doing nothing. You can provide your own
;;; routine, either in C or assembly for doing custom low leve initialization.
;;;
;;; ***************************************************************************
.section libcode
.pubweak __low_level_init
__low_level_init:
return

View File

@ -1,378 +0,0 @@
;;*****************************************************************************
;; Sentinel 65X Kernel
;;
;; src/drivers/vera.s
;;*****************************************************************************
#include "macros.h"
.section code
.public vera_reset
.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_addr0_incr1
.public vera_set_addr1_auto_increment
.public vera_set_addr0_decrement
.public vera_set_addr1_decrement
.extern _Dp
vera_reset:
phb
short_a
; Set the data bank to 0
lda #0
pha
plb
lda #0b10000000
tsb 0xDF05
long_a
plb
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
; Optimization: Combine the most common setting for
; addr0: Set an address, and set INCR0 to 1,
; and DECR0 to 0.
vera_set_addr0_incr1:
phb
short_a
pha
; Set the data bank to 0
lda #0
pha
plb
; Set ADDRSEL to 0.
lda #0b00000001
trb 0xDF05
; Set DECR0 to 0 and INCR0 to 0
lda #0b11111000
trb 0xDF02
lda #0b00010000
tsb 0xDF02
; 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 addr0_incr1_high_bit_set
; Else clear the lowest bit of ADDR0_H
lda #0b00000001
trb 0xDF03
; And exit
bra addr0_incr1_done
addr0_incr1_high_bit_set:
; Set the lowest bit of ADDR0_H
lda #0b00000001
tsb 0xDF03
addr0_incr1_done:
plb
long_a
rts

View File

@ -1,176 +0,0 @@
//*****************************************************************************
// Sentinel 65X Kernel
//
// src/drivers/vera2.c
//*****************************************************************************
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "config.h"
#include "drivers/vera.h"
static inline void vera_init_palette(void);
void
vera_init()
{
vera_reset();
vera_init_palette();
}
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_addr0_incr1(addr);
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_addr0_incr1(addr);
vera_poke_data0((uint8_t)(value & 0x00FF));
vera_poke_data0((uint8_t)(value & 0xFF00) >> 8);
}
void
vera_read(void *dest, uint32_t src, size_t length)
{
uint8_t *dst = dest;
vera_set_addr0_incr1(src);
for (size_t i = 0; i < length; i += 1) {
dst[i] = vera_peek_data0();
}
}
void
vera_write(uint32_t dest, void *src, size_t length)
{
uint8_t *source = src;
vera_set_addr0_incr1(dest);
for (size_t i = 0; i < length; i += 1) {
vera_poke_data0(source[i]);
}
}
void
vera_memset(uint32_t addr, uint8_t value, size_t length)
{
vera_set_addr0_incr1(addr);
for (size_t i = 0; i < length; i += 1) {
vera_poke_data0(value);
}
}
VeraPaletteEntry
vera_get_palette_entry(uint8_t index)
{
uint32_t address = 0x0001FA00 + (index * 2);
vera_set_addr0_incr1(address);
VeraPaletteEntry result;
result.byte_value[0] = vera_peek_data0();
result.byte_value[1] = vera_peek_data0();
return result;
}
void
vera_set_palette_entry(uint8_t index, VeraPaletteEntry value)
{
uint32_t address = 0x0001FA00 + (index * 2);
vera_set_addr0_incr1(address);
vera_poke_data0(value.byte_value[0]);
vera_poke_data0(value.byte_value[1]);
}
void
vera_palette_read(VeraPalette *dest)
{
vera_read(dest, 0x0001FA00, sizeof(VeraPalette));
}
void
vera_palette_write(VeraPalette *src)
{
vera_write(0x0001FA00, src, sizeof(VeraPalette));
}
VeraPaletteEntry
vera_make_palette_entry(uint32_t rgb_value)
{
return (VeraPaletteEntry){
.red = (uint8_t)((rgb_value & 0x00F00000) >> 20),
.green = (uint8_t)((rgb_value & 0x0000F000) >> 12),
.blue = (uint8_t)((rgb_value & 0x000000F0) >> 4)
};
}
static uint32_t const vera_default_palette[256] = {
0x000000, 0x111111, 0x222222, 0x333333, 0x444444, 0x555555, 0x666666, 0x777777,
0x888888, 0x999999, 0xaaaaaa, 0xbbbbbb, 0xcccccc, 0xdddddd, 0xeeeeee, 0xffffff,
0x007f7f, 0x3fbfbf, 0x00ffff, 0xbfffff, 0x8181ff, 0x0000ff, 0x3f3fbf, 0x00007f,
0x0f0f50, 0x7f007f, 0xbf3fbf, 0xf500f5, 0xfd81ff, 0xffc0cb, 0xff8181, 0xff0000,
0xbf3f3f, 0x7f0000, 0x551414, 0x7f3f00, 0xbf7f3f, 0xff7f00, 0xffbf81, 0xffffbf,
0xffff00, 0xbfbf3f, 0x7f7f00, 0x007f00, 0x3fbf3f, 0x00ff00, 0xafffaf, 0x00bfff,
0x007fff, 0x4b7dc8, 0xbcafc0, 0xcbaa89, 0xa6a090, 0x7e9494, 0x6e8287, 0x7e6e60,
0xa0695f, 0xc07872, 0xd08a74, 0xe19b7d, 0xebaa8c, 0xf5b99b, 0xf6c8af, 0xf5e1d2,
0x7f00ff, 0x573b3b, 0x73413c, 0x8e5555, 0xab7373, 0xc78f8f, 0xe3abab, 0xf8d2da,
0xe3c7ab, 0xc49e73, 0x8f7357, 0x73573b, 0x3b2d1f, 0x414123, 0x73733b, 0x8f8f57,
0xa2a255, 0xb5b572, 0xc7c78f, 0xdadaab, 0xededc7, 0xc7e3ab, 0xabc78f, 0x8ebe55,
0x738f57, 0x587d3e, 0x465032, 0x191e0f, 0x235037, 0x3b573b, 0x506450, 0x3b7349,
0x578f57, 0x73ab73, 0x64c082, 0x8fc78f, 0xa2d8a2, 0xe1f8fa, 0xb4eeca, 0xabe3c5,
0x87b48e, 0x507d5f, 0x0f6946, 0x1e2d23, 0x234146, 0x3b7373, 0x64abab, 0x8fc7c7,
0xabe3e3, 0xc7f1f1, 0xbed2f0, 0xabc7e3, 0xa8b9dc, 0x8fabc7, 0x578fc7, 0x57738f,
0x3b5773, 0x0f192d, 0x1f1f3b, 0x3b3b57, 0x494973, 0x57578f, 0x736eaa, 0x7676ca,
0x8f8fc7, 0xababe3, 0xd0daf8, 0xe3e3ff, 0xab8fc7, 0x8f57c7, 0x73578f, 0x573b73,
0x3c233c, 0x463246, 0x724072, 0x8f578f, 0xab57ab, 0xab73ab, 0xebace1, 0xffdcf5,
0xe3c7e3, 0xe1b9d2, 0xd7a0be, 0xc78fb9, 0xc87da0, 0xc35a91, 0x4b2837, 0x321623,
0x280a1e, 0x401811, 0x621800, 0xa5140a, 0xda2010, 0xd5524a, 0xff3c0a, 0xf55a32,
0xff6262, 0xf6bd31, 0xffa53c, 0xd79b0f, 0xda6e0a, 0xb45a00, 0xa04b05, 0x5f3214,
0x53500a, 0x626200, 0x8c805a, 0xac9400, 0xb1b10a, 0xe6d55a, 0xffd510, 0xffea4a,
0xc8ff41, 0x9bf046, 0x96dc19, 0x73c805, 0x6aa805, 0x3c6e14, 0x283405, 0x204608,
0x0c5c0c, 0x149605, 0x0ad70a, 0x14e60a, 0x7dff73, 0x4bf05a, 0x00c514, 0x05b450,
0x1c8c4e, 0x123832, 0x129880, 0x06c491, 0x00de6a, 0x2deba8, 0x3cfea5, 0x6affcd,
0x91ebff, 0x55e6ff, 0x7dd7f0, 0x08ded5, 0x109cde, 0x055a5c, 0x162c52, 0x0f377d,
0x004a9c, 0x326496, 0x0052f6, 0x186abd, 0x2378dc, 0x699dc3, 0x4aa4ff, 0x90b0ff,
0x5ac5ff, 0xbeb9fa, 0x786ef0, 0x4a5aff, 0x6241f6, 0x3c3cf5, 0x101cda, 0x0010bd,
0x231094, 0x0c2148, 0x5010b0, 0x6010d0, 0x8732d2, 0x9c41ff, 0xbd62ff, 0xb991ff,
0xd7a5ff, 0xd7c3fa, 0xf8c6fc, 0xe673ff, 0xff52ff, 0xda20e0, 0xbd29ff, 0xbd10c5,
0x8c14be, 0x5a187b, 0x641464, 0x410062, 0x320a46, 0x551937, 0xa01982, 0xc80078,
0xff50bf, 0xff6ac5, 0xfaa0b9, 0xfc3a8c, 0xe61e78, 0xbd1039, 0x98344d, 0x911437
};
void
vera_init_palette(void)
{
VeraPaletteEntry colour;
for (int i = 0; i < 255; i += 1) {
colour = vera_make_palette_entry(vera_default_palette[i]);
vera_set_palette_entry(i, colour);
}
}

View File

@ -1,202 +0,0 @@
//*****************************************************************************
// Sentinel 65X Kernel
//
// src/drivers/vera_sprites.c
//*****************************************************************************
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "config.h"
#include "drivers/vera.h"
#include "drivers/vera_sprites.h"
static inline uint32_t
vera_get_sprite_offset(uint8_t index)
{
return 0x0001FC00 + (index * 8);
}
void
vera_sprite_set_bitmap_address(uint8_t index, uint32_t address)
{
uint32_t sprite_address = vera_get_sprite_offset(index);
address = address >> 5;
vera_set_addr0_incr1(sprite_address);
vera_poke_data0((uint8_t)(address & 0x000000FF));
vera_poke_data0((uint8_t)(address & 0x0000FF00) >> 8);
}
uint32_t
vera_sprite_get_bitmap_address(uint8_t index)
{
uint32_t sprite_address = vera_get_sprite_offset(index);
vera_set_addr0_incr1(sprite_address);
uint32_t result = 0;
result = (uint32_t)(vera_peek_data0());
result |= ((uint32_t)(vera_peek_data0()) << 8);
result |= (((uint32_t)(vera_peek_data0() & 0b00000001) << 16));
return result;
}
void
vera_sprite_set_bit_depth(uint8_t index, VeraBitDepth depth)
{
uint32_t sprite_address = vera_get_sprite_offset(index);
vera_set_data0_address(sprite_address + 1);
vera_set_addr0_auto_increment(ADDR_INCREMENT_0);
vera_set_addr0_decrement(false);
uint8_t value = vera_peek_data0();
switch (depth) {
case VERA_DEPTH_4BPP:
vera_poke_data0(value & 0b01111111);
break;
case VERA_DEPTH_8BPP:
vera_poke_data0(value | 0b10000000);
break;
default:
break;
}
}
VeraBitDepth
vera_sprite_get_bit_depth(uint8_t index)
{
uint32_t sprite_address = vera_get_sprite_offset(index);
vera_set_data0_address(sprite_address + 1);
vera_set_addr0_auto_increment(ADDR_INCREMENT_0);
vera_set_addr0_decrement(false);
uint8_t value = vera_peek_data0() & 0b10000000;
if (value == 0) {
return VERA_DEPTH_4BPP;
} else {
return VERA_DEPTH_8BPP;
}
}
void
vera_sprite_set_z_order(uint8_t index, VeraSpriteZOrder order)
{
(void) index;
(void) order;
}
VeraSpriteZOrder
vera_sprite_get_z_order(uint8_t index)
{
(void) index;
return SPRITE_ORDER_BOTTOM;
}
void
vera_sprite_set_x_position(uint8_t index, uint16_t position)
{
(void) index;
(void) position;
}
uint16_t
vera_sprite_get_x_position(uint8_t index)
{
(void) index;
return 0;
}
void
vera_sprite_set_y_position(uint8_t index, uint16_t position)
{
(void) index;
(void) position;
}
uint16_t
vera_sprite_get_y_position(uint8_t index)
{
(void) index;
return 0;
}
void
vera_sprite_set_h_flip(uint8_t index, bool state)
{
(void) index;
(void) state;
}
bool
vera_sprite_get_h_flip(uint8_t index)
{
(void) index;
return false;
}
void
vera_sprite_set_v_flip(uint8_t index, bool state)
{
(void) index;
(void) state;
}
bool
vera_sprite_get_v_flip(uint8_t index)
{
(void) index;
return false;
}
void
vera_sprite_set_width(uint8_t index, VeraSpriteSize size)
{
(void) index;
(void) size;
}
VeraSpriteSize
vera_sprite_get_width(uint8_t index)
{
(void) index;
return SPRITE_SIZE_8;
}
void
vera_sprite_set_height(uint8_t index, VeraSpriteSize size)
{
(void) index;
(void) size;
}
VeraSpriteSize
vera_sprite_get_height(uint8_t index)
{
(void) index;
return SPRITE_SIZE_8;
}
void
vera_sprite_set_palette_offset(uint8_t index, uint8_t value)
{
(void) index;
(void) value;
}
uint8_t
vera_sprite_get_palette_offset(uint8_t index)
{
(void) index;
return 0;
}

View File

@ -1,169 +0,0 @@
//*****************************************************************************
// Sentinel 65X Kernel
//
// src/include/kernel.h
//*****************************************************************************
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
#ifndef far
#define far __far
#endif
#ifndef near
#define near __near
#endif
typedef enum {
sys_reset,
sys_get_version,
sys_get_date_time,
sys_set_date_time,
con_ioctl,
con_getc,
con_putc,
con_puts,
con_readline,
con_stat,
sh_exec,
sh_exit,
sh_get_env,
sh_chdir,
sh_pwd,
fs_status,
fs_init,
fs_ioctl,
fs_sector_read,
fs_sector_write,
fs_mkfs,
fs_free,
fs_get_label,
fs_set_label,
file_open,
file_close,
file_read,
file_write,
file_seek,
file_trunc,
file_sync,
file_gets,
file_putc,
file_puts,
file_eof,
file_stat,
file_unlink,
file_rename,
file_chattr,
file_utime,
dir_mkdir,
dir_open,
dir_close,
dir_read,
dir_first,
dir_next
} KernelAPIFunction;
typedef struct date_time_s {
uint8_t seconds;
uint8_t minute;
uint8_t hour;
uint8_t day;
uint8_t month;
uint8_t year;
} DateTimeStamp;
typedef enum con_getc_flags {
CON_GETC_NO_BLOCK = 1 << 6,
CON_GETC_NO_ECHO = 1 << 7
} ConGetcFlags;
typedef enum con_readline_flags {
CON_READLINE_NO_ECHO = 1 << 7
} ConReadlineFlags;
typedef enum con_stat_flags {
CON_STAT_READY = 1 << 7,
CON_STAT_CHAR_AVAILABLE = 1 << 6
} ConStatFlags;
typedef enum file_chattr_flags {
ATTR_READ_ONLY = 1 << 0,
ATTR_ARCHIVE = 1 << 1,
ATTR_SYSTEM = 1 << 2,
ATTR_HIDDEN = 1 << 3,
ATTR_READ_ONLY_MASK = 1 << 4,
ATTR_ARCHIVE_MASK = 1 << 5,
ATTR_SYSTEM_MASK = 1 << 6,
ATTR_HIDDEN_MASK = 1 << 7
} FileChattrFlags;
typedef struct sector_read_s {
uint32_t offset;
uint16_t count;
far void *dest;
} SectorReadArgs;
typedef struct sector_write_s {
uint32_t offset;
uint16_t count;
far void *src;
} SectorWriteArgs;
typedef struct file_read_s {
uint16_t file_handle;
size_t length;
far void *dest;
} FileReadArgs;
typedef struct file_write_s {
uint16_t file_handle;
size_t length;
far void *src;
} FileWriteArgs;
typedef struct file_seek_s {
uint16_t file_handle;
ssize_t offset;
bool relative;
} FileSeekArgs;
typedef struct file_gets_s {
uint16_t file_handle;
far void *dest;
} FileGetsArgs;
typedef struct file_puts_s {
uint16_t file_handle;
far void *src;
} FilePutsArgs;
typedef struct file_rename_s {
far char *src_path;
far char *dest_path;
} FileRenameArgs;
typedef struct file_utime_s {
far char *path;
uint8_t seconds;
uint8_t minute;
uint8_t hour;
uint8_t day;
uint8_t month;
uint8_t year;
} FileUtimeArgs;
typedef struct dir_open_s {
far char *path;
far void *dir;
} DirOpenArgs;
typedf struct dir_read_s {
far void *dir;
far void *file_info;
} DirReadArgs;

View File

@ -1,804 +0,0 @@
;;*****************************************************************************
;; Sentinel 65X Kernel
;;
;; src/interrupts.s
;;*****************************************************************************
#include "macros.h"
.section code
; Return from a COP interrupt
cop_rti .macro
plb
rti
.endm
; Set the data bank register to 0.
set_dbr_0 .macro
pha
lda ##0
short_a
pha
plb
long_a
pla
.endm
; -----------------------------------------------------------------------------
; Initialize the interrupt handler vectors.
.public interrupts_init
interrupts_init:
long_a
sei
lda ##.near(null_handler)
; Emulation mode interrupt vectors.
sta long:0x00FFFE
sta long:0x00FFFA
sta long:0x00FFF8
sta long:0x00FFF4
sta long:0x00FFEE
sta long:0x00FFEC
sta long:0x00FFEA
sta long:0x00FFE8
sta long:0x00FFE6
sta long:0x00FFE4
sta long:0x00FFE2
sta long:0x00FFE0
sta long:0x00FFDE
sta long:0x00FFDC
sta long:0x00FFDA
sta long:0x00FFD8
sta long:0x00FFD6
sta long:0x00FFD4
sta long:0x00FFD2
sta long:0x00FFD0
sta long:0x00FFCE
sta long:0x00FFCC
sta long:0x00FFCA
sta long:0x00FFC8
sta long:0x00FFC6
sta long:0x00FFC4
sta long:0x00FFC2
sta long:0x00FFC0
; Native mode interrupt vectors.
sta long:0x00FFB8
sta long:0x00FFB6
sta long:0x00FFAE
sta long:0x00FFAC
sta long:0x00FFAA
sta long:0x00FFA8
sta long:0x00FFA6
sta long:0x00FFA4
sta long:0x00FFA2
sta long:0x00FFA0
sta long:0x00FF9C
sta long:0x00FF9A
sta long:0x00FF98
sta long:0x00FF96
sta long:0x00FF94
sta long:0x00FF92
sta long:0x00FF92
sta long:0x00FF8E
sta long:0x00FF8C
sta long:0x00FF8A
sta long:0x00FF88
sta long:0x00FF86
sta long:0x00FF84
sta long:0x00FF82
sta long:0x00FF80
; Reset vector
.extern __program_start
lda ##.near(__program_start)
sta long:0x00FFFC
; COP vector (native mode)
lda ##.near(cop_handler_native)
sta long:0x00FFB4
rts
; -----------------------------------------------------------------------------
; The COP handler is the primary interface to the kernel from user code. The
; user program loads the function number into X, and any appropriate arguments
; are loaded in a function-defined manner, and the COP interrupt (with an ignored)
; argument byte) is triggered.
cop_handler_native:
phb
long_a
set_dbr_0
; First, we multiply the function number by 2, to get the jump
; table offset.
pha
txa
asl a
tax
pla
; When we get here, the X register contains the function number.
; A/C, Y, and _Dp[0..7] may or may not contain parameters. None of
; those are expected to be preserved. The job here is just to jump
; to the right handler for the particular function being called,
; without modifying anything but the X register.
;
; Note that, other than using the X register specifically for the
; function number, arguments are passed into COP functions following
; function-specific protocols. Each function's arguments and return
; values are listed near the function itself.
; Now, we do an indirect, indexed jump through the jump table.
jsr (.kbank cop_jump_table,x)
plb
; -----------------------------------------------------------------------------
; Null interrupt handler
;
; This handler intentionally does nothing. It is used to populate interrupt
; vectors that do nothing, without wasting space on multiple such functions.
null_handler:
rti
cop_jump_table:
.word .word0 sys_reset
.word .word0 sys_get_version
.word .word0 sys_get_date_time
.word .word0 sys_set_date_time
.word .word0 con_ioctl
.word .word0 con_getc
.word .word0 con_putc
.word .word0 con_puts
.word .word0 con_readline
.word .word0 con_stat
.word .word0 sh_exec
.word .word0 sh_exit
.word .word0 sh_get_env
.word .word0 sh_chdir
.word .word0 sh_pwd
.word .word0 fs_status
.word .word0 fs_init
.word .word0 fs_ioctl
.word .word0 fs_sector_read
.word .word0 fs_sector_write
.word .word0 fs_mkfs
.word .word0 fs_free
.word .word0 fs_get_label
.word .word0 fs_set_label
.word .word0 file_open
.word .word0 file_close
.word .word0 file_read
.word .word0 file_write
.word .word0 file_seek
.word .word0 file_trunc
.word .word0 file_sync
.word .word0 file_gets
.word .word0 file_putc
.word .word0 file_puts
.word .word0 file_eof
.word .word0 file_stat
.word .word0 file_unlink
.word .word0 file_rename
.word .word0 file_chattr
.word .word0 file_utime
.word .word0 dir_mkdir
.word .word0 dir_open
.word .word0 dir_close
.word .word0 dir_read
; -----------------------------------------------------------------------------
; Soft-reset the system by unconditionally long-jumping to the kernel init
; routine. This function does not return.
;
; Arguments: None
sys_reset:
.extern __program_start
jmp long:__program_start
; -----------------------------------------------------------------------------
; Get the version number of the running kernel. This number is structurally
; equivalent to the following layout:
;
; struct version_number_s {
; const uint8_t version_micro: 8;
; const uint8_t version_minor: 4;
; const uint8_t version_major: 4;
; };
;
; Arguments: None
; Return value:
; C: Version number
sys_get_version:
.extern version_number
lda long:version_number
rts
; -----------------------------------------------------------------------------
; Gets the date and time by populating a data structure passed via a pointer.
; The structure has the following layout:
;
; struct date_time_s {
; uint8_t seconds;
; uint8_t minute;
; uint8_t hour;
; uint8_t day;
; uint8_t month;
; uint8_t year;
; };
;
; Arguments:
; A: Bank of argument
; Y: Address of argument
; Return value:
; A: Error code
sys_get_date_time:
rts
; -----------------------------------------------------------------------------
; Sets the date and time by reading a data structure passed via a pointer.
; The structure has the following layout:
;
; struct date_time_s {
; uint8_t seconds;
; uint8_t minute;
; uint8_t hour;
; uint8_t day;
; uint8_t month;
; uint8_t year;
; };
;
; Arguments:
; A: Bank of argument
; Y: Address of argument
; Return value:
; A: Error code
sys_set_date_time:
rts
; -----------------------------------------------------------------------------
; Configure the console. This can be used to redirect the console from the VGA
; screen to the serial port, for example, or to select the active keyboard
; device.
;
; Arguments:
; C: Bit flags
; Return value:
; A: Error code
con_ioctl:
rts
; -----------------------------------------------------------------------------
; Read a character from stdin.
;
; Arguments:
; A: Option flags
; Bit 7 set: Do not echo to stdout
; Bit 6 set: Do not block, return 0xFF if no character ready
; Return value:
; A: Character value
con_getc:
rts
; -----------------------------------------------------------------------------
; Write a character to stdout.
;
; Arguments:
; A: Character to write
; Return value:
; A: Error code
con_putc:
rts
; -----------------------------------------------------------------------------
; Write a NULL-terminated string to stdout.
;
; Arguments:
; A: Bank of string
; Y: Address of string
; Return value:
; A: Error code
con_puts:
rts
; -----------------------------------------------------------------------------
; Read a line of input from stdin, storing as a NULL-terminated string. That is,
; standard input is read until a newline is encountered.
;
; Arguments:
; A: Bank of destination buffer
; B: Option flags
; Bit 7 set: Do not echo to stdout
; Y: Address of destination buffer
; Return value:
; A: Error code
con_readline:
rts
; -----------------------------------------------------------------------------
; Get console status.
;
; Arguments: None
; Return value:
; A: Condition flags
; Bit 7 set: Console is ready for input
; Bit 6 set: Character is ready to be read from stdin
con_stat:
rts
; -----------------------------------------------------------------------------
; Load a program from a file and run it. This function does not return.
;
; Arguments:
; A: Bank of file path string
; Y: Address of file path string
sh_exec:
rts
; -----------------------------------------------------------------------------
; Exit the running user program, returning to the shell with an exit code. This
; function does not return. If there is no shell specified in the kernel's
; memory, then the kernel will load and run a PGZ binary stored in ROM.
;
; Arguments:
; A: Exit code
sh_exit:
rts
; -----------------------------------------------------------------------------
; Get the address of the shell environment data.
;
; Arguments: None
; Return value:
; A: Bank of environment
; X: Address of environment
sh_get_env:
rts
; -----------------------------------------------------------------------------
; Set the current working directory.
;
; Arguments:
; A: Bank of path string
; Y: Address of path string
; Return value:
; A: Error code
sh_chdir:
rts
; -----------------------------------------------------------------------------
; Get the current working directory as a path string. The string belongs to the
; kernel, and must not be modified or freed.
;
; Arguments: None
; Return value:
; A: Bank of path string
; X: Address of path string
sh_pwd:
rts
; -----------------------------------------------------------------------------
; Get the status flags of the SD card.
;
; Arguments: None
; Return value:
; A: Status flags
fs_status:
rts
; -----------------------------------------------------------------------------
; Initialize (mount) the SD card
;
; Arguments: None
; Return value:
; A: Error code
fs_init:
rts
; -----------------------------------------------------------------------------
; Send a command to the SD card.
;
; Arguments:
; A: Command byte
; Return value:
; A: Error code
fs_ioctl:
rts
; -----------------------------------------------------------------------------
; Read a number of raw sectors from the SD card. Arguments are passed in a data
; structure with the following layout:
;
; struct sector_read_s {
; uint32_t offset;
; uint16_t count;
; far void *dest;
; };
;
; Arguments:
; A: Bank of argument
; Y: Address of argument
; Return value:
; A: Error code
; X: Number of sectors actually read
fs_sector_read:
rts
; -----------------------------------------------------------------------------
; Write a number of raw sectors to the SD card. Arguments are passed in a data
; structure with the following layout:
;
; struct sector_write_s {
; uint32_t offset;
; uint16_t count;
; far void *src;
; };
;
; Arguments:
; A: Bank of argument
; Y: Address of argument
; Return value:
; A: Error code
; X: Number of sectors actually written
fs_sector_write:
rts
; -----------------------------------------------------------------------------
; Format the inserted SD card, removing any existing data.
;
; Arguments:
; A: Bank of volume label string
; Y: Address of volume label string
; Return value:
; A: Error code
fs_mkfs:
rts
; -----------------------------------------------------------------------------
; Get the amount of free space (in bytes) on the filesystem.
;
; Arguments: None
; Return value:
; X: High-order 32 bits of free space
; Y: Low-order 32 bits of free space
fs_free:
rts
; -----------------------------------------------------------------------------
; Get the volume label of the SD card. The string is written to a buffer owned
; by the caller.
;
; Arguments:
; A: Bank of volume label string
; Y: Address of volume label string
; Return value:
; A: Error code
fs_get_label:
rts
; -----------------------------------------------------------------------------
; Set the volume label of the SD card.
;
; Arguments:
; A: Bank of volume label string
; Y: Address of volume label string
; Return value:
; A: Error code
fs_set_label:
rts
; -----------------------------------------------------------------------------
; Open a file given a file path and mode settings.
;
; Arguments:
; A: Bank of path string
; B: Mode flags
; Y: Address of path string
; Return value:
; A: Error code
; X: File handle
file_open:
rts
; -----------------------------------------------------------------------------
; Close an open file.
;
; Arguments:
; C: File handle
; Return value:
; A: Error code
file_close:
rts
; -----------------------------------------------------------------------------
; Read some number of bytes from a file. Arguments are passed throgh a data
; structure with the following layout:
;
; struct file_read_s {
; uint16_t file_handle;
; size_t length;
; void *dest;
; }
;
; Arguments:
; A: Bank of argument
; Y: Address of argument
; Return value:
; A: Error code
; X: Number of bytes actually read
file_read:
rts
; -----------------------------------------------------------------------------
; Write some number of bytes to a file. Arguments are passed throgh a data
; structure with the following layout:
;
; struct file_write_s {
; uint16_t file_handle;
; size_t length;
; void *src;
; }
;
; Arguments:
; A: Bank of argument
; Y: Address of argument
; Return value:
; A: Error code
; X: Number of bytes actually written
file_write:
rts
; -----------------------------------------------------------------------------
; Moves the file index. Arguments are passed throgh a data structure with the
; following layout:
;
; struct file_seek_s {
; uint16_t file_handle;
; ssize_t offset;
; bool relative;
; }
;
; Arguments:
; A: Bank of argument
; Y: Address of argument
; Return value:
; A: Error code
file_seek:
rts
; -----------------------------------------------------------------------------
; Truncate (shorten) an open file by setting the current index as the end of
; the file data.
;
; Arguments:
; C: File handle
; Return value:
; A: Error code
file_trunc:
rts
; -----------------------------------------------------------------------------
; Ensure that any pending writes to the file have been completed.
;
; Arguments:
; C: File handle
; Return value:
; A: Error code
file_sync:
rts
; -----------------------------------------------------------------------------
; Read bytes from the file into a provided buffer until a newline is read, and
; terminate the buffer with a NULL byte.
;
; struct file_gets_s {
; uint16_t file_handle;
; void *dest;
; }
;
; Arguments:
; A: Bank of argument
; Y: Address of argument
; Return value:
; A: Error code
file_gets:
rts
; -----------------------------------------------------------------------------
; Write a single character to the file.
;
; Arguments:
; A: Character value
; Y: File handle
;
; Return value:
; A: Error code
file_putc:
rts
; -----------------------------------------------------------------------------
; Write a null-terminated string to the file, replacing the NULL with a newline
; character.
;
; struct file_puts_s {
; uint16_t file_handle;
; void *src;
; }
;
; Arguments:
; A: Bank of argument
; Y: Address of argument
; Return value:
; A: Error code
file_puts:
rts
; -----------------------------------------------------------------------------
; Check if the current file index is at the end of the file's data.
;
; Arguments:
; C: File handle
;
; Return value:
; A: Non-zero if the index is at the end of the file's data.
file_eof:
rts
; -----------------------------------------------------------------------------
; Given a NULL-terminated pathname string, determine if the file so specified
; actually exists.
;
; Arguments:
; A: Bank of pathname string
; Y: Address of pathname string
; Return value:
; A: Error code
file_stat:
rts
; -----------------------------------------------------------------------------
; Given a NULL-terminated pathname string, deletes the specified file or
; directory, if it exists.
;
; Arguments:
; A: Bank of pathname string
; Y: Address of pathname string
; Return value:
; A: Error code
file_unlink:
rts
; -----------------------------------------------------------------------------
; Given two path strings, rename/move the file to the new path/name.
; Arguments are passed in a structure with the following layout:
;
; struct file_rename_s {
; char *src_path;
; char *dest_path;
; }
;
; Arguments:
; A: Bank of argument
; Y: Address of argument
; Return value:
; A: Error code
file_rename:
rts
; -----------------------------------------------------------------------------
; Given a NULL-terminated pathname string, if the file exists, then alter the
; file's attributes as specified: for each of the mask bits which is set,
; set the file's attribute to the value specified. For example, if the
; B argument is 0b10001000, then the hidden attribute of the file will
; be set to "true" and no other attribute will be changed.
;
; Arguments:
; A: Bank of pathname string
; B: New attribute state bit flags:
; Bit 0: Read-Only
; Bit 1: Archive
; Bit 2: System
; Bit 3: Hidden
; Bit 4: Read-Only Mask
; Bit 5: Archive Mask
; Bit 6: System Mask
; Bit 7: Hidden Mask
; Y: Address of pathname string
; Return value:
; A: Error code
file_chattr:
rts
; -----------------------------------------------------------------------------
; Given a NULL-terminated pathname string and time and date information,
; alter the time/date stamp of the file as specified. Arguments are passed
; in a data structure with the following layout:
;
; struct utime_s {
; char *path;
; uint8_t seconds;
; uint8_t minute;
; uint8_t hour;
; uint8_t day;
; uint8_t month;
; uint8_t year;
; };
;
; Arguments:
; A: Bank of argument
; Y: Address of argument
; Return value:
; A: Error code
file_utime:
rts
; -----------------------------------------------------------------------------
; Given a NULL-terminated pathname string, if no file or directly exists
; matching the pathname, create a new directory at that path.
;
; Arguments:
; A: Bank of pathname string
; Y: Address of pathname string
; Return value:
; A: Error code
dir_mkdir:
rts
; -----------------------------------------------------------------------------
; Given a NULL-terminated pathname string, open the specified directory.
; The caller provides a pointer to a buffer to contain the directory information.
; This pointer is then used with the other dir_* functions.
;
; struct dir_open_s {
; char *path;
; void *dir;
; };
;
; Arguments:
; A: Bank of argument
; Y: Address of argument
; Return value:
; A: Error code
dir_open:
rts
; -----------------------------------------------------------------------------
; Given a pointer to a structure populated by dir_open, close the specified
; directory.
;
; Arguments:
; A: Bank of pointer
; Y: Address of pointer
; Return value:
; A: Error code
dir_close:
rts
; -----------------------------------------------------------------------------
; Given a pointer to a structure populated by dir_open and a pointer to a file
; information structure buffer, read the next directory item from the directory.
; Repeated invocations of this function on a single directory read the items
; one at a time, until the last one, at which point the read item will have
; a NULL name; reading will then loop back to the beginning. The arguments are
; passed in a data structure with the following layout:
;
; struct dir_read_s {
; void *dir;
; void *file_info;
; };
;
; Arguments:
; A: Bank of argument
; Y: Address of argument
; Return value:
; A: Error code
dir_read:
rts

72
src/irq.s Normal file
View File

@ -0,0 +1,72 @@
.section code
.section irq_handlers
.logical $008100
empty_irq_handler .proc
phb
phd
.long_a
.long_i
pha
phx
phy
jmp irq_exit
.endproc
nmi_handler .proc
rti
.endproc
irq_exit .proc
.long_a
.long_i
ply
plx
pla
pld
plb
rti
.endproc
.endlogical
.endsection irq_handlers
.section irq_vectors
.logical $00FF80
.addr empty_irq_handler ; Timer 0 (Native Mode)
.addr empty_irq_handler ; Timer 1 (Native Mode)
.addr empty_irq_handler ; Timer 2 (Native Mode)
.addr empty_irq_handler ; Timer 3 (Native Mode)
.addr empty_irq_handler ; Timer 4 (Native Mode)
.addr empty_irq_handler ; Timer 5 (Native Mode)
.addr empty_irq_handler ; Timer 6 (Native Mode)
.addr empty_irq_handler ; Timer 7 (Native Mode)
.addr empty_irq_handler ; PE56 (Native Mode)
.addr empty_irq_handler ; NE57 (Native Mode)
.addr empty_irq_handler ; PE60 (Native Mode)
.addr empty_irq_handler ; PE62 (Native Mode)
.addr empty_irq_handler ; NE64 (Native Mode)
.addr empty_irq_handler ; NE66 (Native Mode)
.addr empty_irq_handler ; PIB (Native Mode)
.addr empty_irq_handler ; IRQ (Native Mode)
.addr empty_irq_handler ; UART0 RX (Native Mode)
.addr empty_irq_handler ; UART0 TX (Native Mode)
.addr empty_irq_handler ; UART1 RX (Native Mode)
.addr empty_irq_handler ; UART1 TX (Native Mode)
.addr empty_irq_handler ; UART2 RX (Native Mode)
.addr empty_irq_handler ; UART2 TX (Native Mode)
.addr empty_irq_handler ; UART3 RX (Native Mode)
.addr empty_irq_handler ; UART3 TX (Native Mode)
.addr empty_irq_handler ; RESERVED
.addr empty_irq_handler ; RESERVED
.addr empty_irq_handler ; COP (Native Mode)
.addr empty_irq_handler ; BRK (Native Mode)
.addr empty_irq_handler ; ABORT (Native Mode)
.addr nmi_handler ; NMI (Native Mode)
.addr empty_irq_handler ; RESERVED
.addr empty_irq_handler ; RESERVED
.endlogical
.endsection irq_vectors
.endsection code

View File

@ -1,35 +0,0 @@
//*****************************************************************************
// Sentinel 65X Kernel
//
// src/main.c
//*****************************************************************************
#include <stdint.h>
#include "config.h"
#include "interrupts.h"
#include "drivers/vera.h"
// This structure essentially divides a uint16_t into four
// fields, each of which holds a version number.
struct version_number_s {
const uint8_t version_micro: 8;
const uint8_t version_minor: 4;
const uint8_t version_major: 4;
};
struct version_number_s version_number = {
.version_major = 0,
.version_minor = 0,
.version_micro = 1,
};
void
main(void)
{
interrupts_init();
vera_init();
for (;;) {}
}

39
src/main.s Normal file
View File

@ -0,0 +1,39 @@
.section code
main .proc
; Start FCLK
lda #%00000001
tsb SSCR
; Disable the on-CPU ROM
lda #%10001001
tsb BCR
; Disable secondary interrupt sources
stz UIER
stz TIER
stz EIER
; Disable all timers
stz TER
; Set P5.4 and P5.5 as output
lda #%00110000
tsb PDD5
; Set P6.1 as output
lda #%00000010
tsb PDD6
; Disable on-chip SRAM
lda #%00000100
tsb SSCR
; Select FCLK as the clock source
lda #%11111010
tsb SSCR
; Initialize the VERA
jsl vera_init
.endproc
.endsection

39
src/memory.s Normal file
View File

@ -0,0 +1,39 @@
; src/memory.s
;
; This file provides the structure of the ROM firmware's memory
; layout, as well as filler bytes ($EA) for all the unused space.
; Rather than pre-assign procedures to specific addresses, we divide
; the firmware space up into sections and let the assembler decide
; the specifics, wherever possible.
;
; The wrinkle in this is the boot region, which is visible at $008000
; as long as /CS4 is active; part of the early boot sequence long jumps
; into the "upper" ROM space in /CS7, in order to allow shutting off
; /CS4, freeing the space for RAM in /CS5; part of this process is
; filling the area in RAM where the CPU expects the 64 interrupt
; vectors.
.include "sentinel65x.i"
* = 000000
.dsection zp
* = $C00000
.dsection code
.section code
.fill $C08000 - *, $EA
* = $C08000
.dsection boot
.fill $C08100 - *, $EA
* = $C08100
.dsection irq_handlers
.fill $C0FF80 - *, $EA
* = $C0FF80
.dsection irq_vectors
.endsection code
.fill $C80000 - *, $EA

View File

@ -1,114 +0,0 @@
//*****************************************************************************
// Sentinel 65X Kernel
//
// src/stubs.c
//*****************************************************************************
// Stub functions which the C library needs in order to function.
#include <stddef.h>
#include <stdio.h>
#include "config.h"
far int
_Stub_open(const char *path, int oflag, ...)
{
(void) path;
(void) oflag;
return -1;
}
far int
_Stub_close(int fd)
{
(void) fd;
return -1;
}
far int
_Stub_access(const char *path, int mode)
{
(void) path;
(void) mode;
return -1;
}
far long
_Stub_lseek(int fd, long offset, int whence)
{
(void) fd;
(void) offset;
(void) whence;
return -1;
}
far int
_Stub_fgetpos(int fd, fpos_t *pos)
{
(void) fd;
(void) pos;
return -1;
}
far int
_Stub_fsetpos(int fd, const fpos_t *pos)
{
(void) fd;
(void) pos;
return -1;
}
far size_t
_Stub_read(int fd, void *buf, size_t count)
{
(void) fd;
(void) buf;
(void) count;
return 0;
}
far size_t
_Stub_write(int fd, const void *buf, size_t count)
{
(void) fd;
(void) buf;
(void) count;
return 0;
}
far int
_Stub_rename(const char *oldpath, const char *newpath)
{
(void) oldpath;
(void) newpath;
return -1;
}
far int
_Stub_remove(const char *path)
{
(void) path;
return -1;
}
far void
_Stub_exit(int exitCode)
{
(void) exitCode;
return;
}
far char**
_Stub_environ(void)
{
return NULL;
}
far void
_Stub_assert(const char *filename, int linenum)
{
(void) filename;
(void) linenum;
return;
}

10
src/vera.s Normal file
View File

@ -0,0 +1,10 @@
.section code
vera_init .proc
pha
pla
rtl
.endproc
.endsection

209
stuff.s Normal file
View File

@ -0,0 +1,209 @@
.include "sentinel65x.i"
* = $C8000
.null "WDC"
jml w65c265s_init
w65c265s_init .proc
; Disable standard interrupts
sei
.short_a
.long_i
; Set data bank to 0
lda #0
pha
plb
.databank 0
; Set direct page to $0000
pea $0000
pld
.dpage $0000
; Set stack to $001FF
ldx #$01FF
txs
; Start FCLK
lda #%00000001
tsb SSCR
; Disable the on-CPU ROM
lda #%10001001
tsb BCR
; Disable secondary interrupt sources
stz UIER
stz TIER
stz EIER
; Enable all used chip select lines.
lda #%11110011
sta PCS7
; Disable all timers
stz TER
; Set P5.4 and P5.5 as output
lda #%00110000
tsb PDD5
; Set P6.1 as output
lda #%00000010
tsb PDD6
; Disable on-chip SRAM
lda #%00000100
tsb SSCR
; Select FCLK as the clock source
lda #%11111010
tsb SSCR
; Initialize the VERA
jsl vera_init
; Jump to entry point.
jml start
.endproc
blink_red .proc
pha
phx
; Turn on the red LED
lda #%00010000
tsb PD5
ldx #02
jsl delay
; Turn off the red LED
lda #%00010000
trb PD5
plx
pla
rtl
.endproc
blink_green .proc
pha
phx
; Turn on the green LED
lda #%00100000
tsb PD5
ldx #02
jsl delay
; Turn off the green LED
lda #%00100000
trb PD5
plx
pla
rtl
.endproc
blink_blue .proc
pha
phx
; Turn on the blue LED
lda #%00000010
tsb PD6
ldx #02
jsl delay
; Turn off the blue LED
lda #%00000010
trb PD6
plx
pla
rtl
.endproc
; Delay X times.
delay .proc
phy
loop_x
ldy #$FFFF
loop_y
dey
bne loop_y
dex
bne loop_x
ply
rtl
.endproc
start .proc
jsl blink_blue
main_loop
nop
bra main_loop
.endproc
empty_irq_handler .proc
phb
phd
.long_a
.long_i
pha
phx
phy
jmp irq_exit
.endproc
nmi_handler .proc
jsl blink_red
jsl blink_green
jsl blink_blue
rti
.endproc
irq_exit .proc
.long_a
.long_i
ply
plx
pla
pld
plb
rti
.endproc
vera_init .proc
pha
jsl blink_red
jsl blink_green
pla
rtl
.endproc
.fill $FF80 - *, 0
* = $FF80
.fill $FFBA - *, empty_irq_handler
* = $FFBA
.word nmi_handler
.fill $FFFF - *, empty_irq_handler
.fill 524288 - *, 0