Rewrite from scratch using 64tass.
This commit is contained in:
parent
edc645aee7
commit
c61597ae46
43
Makefile
43
Makefile
|
@ -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:
|
|
@ -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.
|
|
@ -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)
|
||||
))
|
|
@ -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)
|
|
@ -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)
|
|
@ -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))))
|
|
@ -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);
|
|
@ -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);
|
|
@ -1,11 +0,0 @@
|
|||
//*****************************************************************************
|
||||
// Sentinel 65X Kernel
|
||||
//
|
||||
// include/interrupts.h
|
||||
//*****************************************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
|
||||
extern void interrupts_init(void);
|
106
include/macros.h
106
include/macros.h
|
@ -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
|
|
@ -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"
|
|
@ -1,9 +0,0 @@
|
|||
//*****************************************************************************
|
||||
// Sentinel 65X Kernel
|
||||
//
|
||||
// include/sys/types.h
|
||||
//*****************************************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef long ssize_t;
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
143
src/cstartup.s
143
src/cstartup.s
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
804
src/interrupts.s
804
src/interrupts.s
|
@ -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
|
|
@ -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
|
35
src/main.c
35
src/main.c
|
@ -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 (;;) {}
|
||||
}
|
|
@ -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
|
|
@ -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
|
114
src/stubs.c
114
src/stubs.c
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
.section code
|
||||
|
||||
vera_init .proc
|
||||
pha
|
||||
|
||||
pla
|
||||
rtl
|
||||
.endproc
|
||||
|
||||
.endsection
|
|
@ -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
|
Loading…
Reference in New Issue