Initial code import
This commit is contained in:
commit
e562ef8dab
|
@ -0,0 +1,36 @@
|
|||
include config/config.mk
|
||||
|
||||
TARGET := sentinel-65x-512K
|
||||
|
||||
.PHONY: all
|
||||
all: build/$(TARGET).bin
|
||||
|
||||
include config/boot.mk
|
||||
include config/bios.mk
|
||||
|
||||
build/$(TARGET).bin: build/boot.bin build/bios.bin
|
||||
#Create an empty .bin file.
|
||||
@dd if=/dev/zero of=$@ bs=1024 count=512
|
||||
|
||||
# Add the boot module at offset 0x008000
|
||||
@dd if=build/boot.bin of=$@ bs=1024 seek=32 conv=notrunc
|
||||
|
||||
# Add the bios module at offset 0x008300
|
||||
@dd if=build/bios.bin of=$@ bs=1 seek=33536 conv=notrunc
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@find build -type f \( \
|
||||
-name '*.pgz' -o \
|
||||
-name '*.bin' -o \
|
||||
-name '*.elf' -o \
|
||||
-name '*.a' -o \
|
||||
-name '*.lst' \
|
||||
\) -delete
|
||||
@find src -type f \( \
|
||||
-name '*.o' \
|
||||
\) -delete
|
||||
|
||||
.PHONY: flash
|
||||
flash: $(TARGET).bin
|
||||
$(MP) $(MPFLAGS) -w $<
|
|
@ -0,0 +1,12 @@
|
|||
BIOS_ASM_SRC := $(wildcard src/bios/*.s)
|
||||
BIOS_C_SRC := $(wildcard src/bios/*.c)
|
||||
|
||||
BIOS_OBJ := $(BIOS_ASM_SRC:.s=.o)
|
||||
BIOS_OBJ += $(BIOS_C_SRC:.c=.o)
|
||||
|
||||
BIOS_LDFLAGS := --list-file build/bios.lst
|
||||
|
||||
build/bios.bin: $(BIOS_OBJ)
|
||||
echo "Linking $@..."
|
||||
$(LD) -o $@ config/bios.scm $(LDFLAGS) $(BIOS_LDFLAGS) $^
|
||||
mv build/bios.raw $@
|
|
@ -0,0 +1,41 @@
|
|||
(define memories '(
|
||||
|
||||
(memory RAM
|
||||
(address (#x000200 . #x001FFF))
|
||||
(section zhuge)
|
||||
(section znear)
|
||||
(section zdata)
|
||||
(section heap)
|
||||
)
|
||||
|
||||
(memory ROM
|
||||
(address (#xC08300 . #xC0FFFF))
|
||||
(section code)
|
||||
(section farcode)
|
||||
(section cdata)
|
||||
(section switch)
|
||||
(section near)
|
||||
(section data)
|
||||
(section (irq_trampolines #xC0F000))
|
||||
(section (irq_vectors #xC0FF80))
|
||||
)
|
||||
|
||||
(memory Stack
|
||||
(address (#x000100 . #x0001FF))
|
||||
(section (stack #x00100))
|
||||
)
|
||||
|
||||
(memory DirectPage
|
||||
(address (#x000000 . #x0000FF))
|
||||
(section
|
||||
(registers #x000004)
|
||||
(ztiny)
|
||||
)
|
||||
)
|
||||
|
||||
(block stack (size #x100)) ; machine stack size
|
||||
|
||||
(base-address _DirectPageStart DirectPage 0)
|
||||
|
||||
(base-address _NearBaseAddress ROM 0)
|
||||
))
|
|
@ -0,0 +1,10 @@
|
|||
BOOT_SRC := $(wildcard src/boot/*.s)
|
||||
|
||||
BOOT_OBJ := $(BOOT_SRC:.s=.o)
|
||||
|
||||
BOOT_LDFLAGS := --list-file build/boot.lst
|
||||
|
||||
build/boot.bin: $(BOOT_OBJ)
|
||||
@echo "Linking $@..."
|
||||
@$(LD) -o $@ config/boot.scm $(LDFLAGS) $(BOOT_LDFLAGS) $^
|
||||
@mv build/boot.raw $@
|
|
@ -0,0 +1,36 @@
|
|||
(define memories '(
|
||||
|
||||
(memory Code
|
||||
(address (#x008000 . #x0080FF))
|
||||
(section code)
|
||||
(section cdata)
|
||||
(section switch)
|
||||
)
|
||||
|
||||
(memory Data
|
||||
(address (#x008100 . #x0081FF))
|
||||
(section near)
|
||||
(section data)
|
||||
(section znear)
|
||||
(section zdata)
|
||||
)
|
||||
|
||||
(memory Stack
|
||||
(address (#x000100 . #x0001FF))
|
||||
(section (stack #x00100))
|
||||
)
|
||||
|
||||
(memory DirectPage
|
||||
(address (#x000000 . #x0000FF))
|
||||
(section
|
||||
(registers #x000004)
|
||||
(ztiny)
|
||||
)
|
||||
)
|
||||
|
||||
(block stack (size #x100)) ; machine stack size
|
||||
|
||||
(base-address _DirectPageStart DirectPage 0)
|
||||
|
||||
(base-address _NearBaseAddress Data 0)
|
||||
))
|
|
@ -0,0 +1,61 @@
|
|||
SHELL := bash
|
||||
CC := cc65816
|
||||
AS := as65816
|
||||
AR := nlib
|
||||
LD := ln65816
|
||||
MP := minipro
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .s .o .a
|
||||
|
||||
CFLAGS := -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
|
||||
|
||||
MPFLAGS := -p SST39LF040@PLCC32
|
||||
|
||||
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
|
||||
|
||||
LDFLAGS := --no-data-init-table-section \
|
||||
--rtattr cstartup=sentinel65x \
|
||||
--verbose \
|
||||
--output-format raw
|
||||
|
||||
ifeq ($(ENABLE_RELEASE_BUILD), "true")
|
||||
CFLAGS += -DRELEASE_BUILD
|
||||
CFLAGS += -DNDEBUG
|
||||
else
|
||||
CFLAGS += -DDEBUG
|
||||
endif
|
||||
|
||||
%.o: %.c
|
||||
@echo "Compiling $@..."
|
||||
@$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
%.o: %.s
|
||||
@echo "Assembling $@..."
|
||||
@$(AS) $(ASFLAGS) -o $@ $<
|
|
@ -0,0 +1,22 @@
|
|||
# Shells
|
||||
|
||||
Turaco-DOS reserves a portion of main memory for a "shell", a
|
||||
program which exists to load and run other programs, and handle
|
||||
their return values. This shell might be a command line, or some
|
||||
other program that manages other programs, such as a batch file
|
||||
interpreter.
|
||||
|
||||
The active shell has a "resident" portion of memory, which stays
|
||||
in memory as long as the shell is active, and a "transient" portion
|
||||
of memory which is only used while the shell is not running an
|
||||
external program.
|
||||
|
||||
When the shell runs a program, and that program exits, its main
|
||||
function returns a two-byte value; this value is stored in a
|
||||
specific memory address, and used by the shell as the "status"
|
||||
code for the program's exit. Like Unix, a zero value is considered
|
||||
a normal exit, with any positive value being some type of error.
|
||||
|
||||
Additionaly, when running a program, the shell can provide the
|
||||
program with a sequence of arguments, which populate the two
|
||||
arguments to the main() function.
|
Binary file not shown.
|
@ -0,0 +1,67 @@
|
|||
#ifndef __MACROS_H
|
||||
#define __MACROS_H
|
||||
|
||||
#ifdef __CALYPSI_ASSEMBLER__
|
||||
|
||||
#ifdef __CALYPSI_CODE_MODEL_SMALL__
|
||||
|
||||
#define libcode code
|
||||
|
||||
call .macro dest
|
||||
jsr \dest
|
||||
.endm
|
||||
|
||||
return .macro
|
||||
rts
|
||||
.endm
|
||||
|
||||
jump .macro dest
|
||||
jmp \dest
|
||||
.endm
|
||||
|
||||
#else
|
||||
|
||||
#define libcode farcode
|
||||
|
||||
call .macro dest
|
||||
jsl \dest
|
||||
.endm
|
||||
|
||||
return .macro
|
||||
rtl
|
||||
.endm
|
||||
|
||||
jump .macro dest
|
||||
jmp long:\dest
|
||||
.endm
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// 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_LARGE__)
|
||||
.rtmodel codeModel,"large"
|
||||
#else
|
||||
#pragma GCC error "unexpected code model"
|
||||
#endif
|
||||
|
||||
#endif // __CALYPSI_CODE_MODEL_SMALL__
|
||||
#endif // __CALYPSI_ASSEMBLER__
|
||||
#endif // __MACROS_H
|
|
@ -0,0 +1,38 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// boot/w65c816s.h
|
||||
// Assembly defines for the 65C816 architecture
|
||||
//
|
||||
// Copyright © 2024 Kyle J Cardoza <Kyle.Cardoza@icloud.com>
|
||||
|
||||
#define native_mode \
|
||||
clc \
|
||||
xce
|
||||
|
||||
#define long_a rep #0x20
|
||||
|
||||
#define short_a sep #0x20
|
||||
|
||||
#define long_i rep #0x10
|
||||
|
||||
#define short_i sep #0x10
|
||||
|
||||
#define save_registers \
|
||||
php \
|
||||
long_a \
|
||||
long_i \
|
||||
pha \
|
||||
phx \
|
||||
phy \
|
||||
short_a \
|
||||
long_i
|
||||
|
||||
#define restore_registers \
|
||||
long_a \
|
||||
long_i \
|
||||
ply \
|
||||
plx \
|
||||
pla \
|
||||
plp \
|
||||
short_a \
|
||||
long_i
|
|
@ -0,0 +1,14 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// boot/sentinel65x.h
|
||||
// Toplevel header for Sentinel 65X ROM firmware boot module
|
||||
//
|
||||
// Copyright © 2024 Kyle J Cardoza <Kyle.Cardoza@icloud.com>
|
||||
|
||||
#define CPU_SPEED_HZ 8000000
|
||||
#define UART3_BAUD_RATE 9600
|
||||
#define UART3_TIMER_VALUE (CPU_SPEED_HZ / (16 * UART3_BAUD_RATE) - 1)
|
||||
|
||||
#include "65c816.h"
|
||||
#include "w65c265s.h"
|
||||
#include "vera.h"
|
|
@ -0,0 +1,124 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// boot/vera.h
|
||||
// Assembly language defines for the VERA chip
|
||||
//
|
||||
// Copyright © 2024 Kyle J Cardoza <Kyle.Cardoza@icloud.com>
|
||||
|
||||
#define AUTO_NONE 0x000000
|
||||
#define AUTO_INC_1 0x100000
|
||||
#define AUTO_INC_2 0x200000
|
||||
#define AUTO_INC_4 0x300000
|
||||
#define AUTO_INC_8 0x400000
|
||||
#define AUTO_INC_16 0x500000
|
||||
#define AUTO_INC_32 0x600000
|
||||
#define AUTO_INC_64 0x700000
|
||||
#define AUTO_INC_128 0x800000
|
||||
#define AUTO_INC_256 0x900000
|
||||
#define AUTO_INC_512 0xA00000
|
||||
#define AUTO_INC_40 0xB00000
|
||||
#define AUTO_INC_80 0xC00000
|
||||
#define AUTO_INC_160 0xD00000
|
||||
#define AUTO_INC_320 0xE00000
|
||||
#define AUTO_INC_640 0xF00000
|
||||
|
||||
#define DISABLED 0
|
||||
#define ENABLED 1
|
||||
|
||||
#define VERA_L_BPP1 0b00000000
|
||||
#define VERA_L_BPP2 0b00000001
|
||||
#define VERA_L_BPP4 0b00000010
|
||||
#define VERA_L_BPP8 0b00000011
|
||||
|
||||
#define VERA_L_BITMAP 0b00000100
|
||||
#define VERA_L_T256C 0b00001000
|
||||
|
||||
#define VERA_L_32W 0b00000000
|
||||
#define VERA_L_64W 0b00010000
|
||||
#define VERA_L_128W 0b00100000
|
||||
#define VERA_L_256W 0b00110000
|
||||
|
||||
#define VERA_L_32H 0b00000000
|
||||
#define VERA_L_64H 0b01000000
|
||||
#define VERA_L_128H 0b10000000
|
||||
#define VERA_L_256H 0b11000000
|
||||
|
||||
#define VERA_TILESIZE8x8 0b00000000
|
||||
#define VERA_TILESIZE16x8 0b00000001
|
||||
#define VERA_TILESIZE8x16 0b00000010
|
||||
#define VERA_TILESIZE16x16 0b00000011
|
||||
|
||||
// The base address of the VERA chip
|
||||
#define VERA_BASE 0x00DF00
|
||||
|
||||
// Offsets (relative to VERA_BASE) for each VERA register
|
||||
|
||||
#define VERA_ADDRx_L VERA_BASE + 00
|
||||
#define VERA_ADDRx_M VERA_BASE + 01
|
||||
#define VERA_ADDRx_H VERA_BASE + 02
|
||||
|
||||
// Accssible with ADDRSEL 0
|
||||
#define VERA_ADDR0_L VERA_BASE + 00
|
||||
#define VERA_ADDR0_M VERA_BASE + 01
|
||||
#define VERA_ADDR0_H VERA_BASE + 02
|
||||
|
||||
// Accssible with ADDRSEL 1
|
||||
#define VERA_ADDR1_L VERA_BASE + 00
|
||||
#define VERA_ADDR1_M VERA_BASE + 01
|
||||
#define VERA_ADDR1_H VERA_BASE + 02
|
||||
|
||||
#define VERA_DATA_0 VERA_BASE + 0x03
|
||||
#define VERA_DATA_1 VERA_BASE + 0x04
|
||||
|
||||
#define VERA_CTRL VERA_BASE + 0x05
|
||||
#define VERA_IEN VERA_BASE + 0x06
|
||||
#define VERA_ISR VERA_BASE + 0x07
|
||||
#define VERA_IRQLINE_L VERA_BASE + 0x08
|
||||
#define VERA_SCANLINE_L VERA_BASE + 0x08
|
||||
|
||||
// Accssible with DCSEL 0
|
||||
#define VERA_DC_VIDEO VERA_BASE + 0x09
|
||||
#define VERA_DC_HSCALE VERA_BASE + 0x0A
|
||||
#define VERA_DC_VSCALE VERA_BASE + 0x0B
|
||||
#define VERA_DC_BORDER VERA_BASE + 0x0C
|
||||
|
||||
// Accssible with DCSEL 1
|
||||
#define VERA_DC_HSTART VERA_BASE + 0x09
|
||||
#define VERA_DC_HSTOP VERA_BASE + 0x0A
|
||||
#define VERA_DC_VSTART VERA_BASE + 0x0B
|
||||
#define VERA_DC_VSTOP VERA_BASE + 0x0C
|
||||
|
||||
// Layer 0
|
||||
#define VERA_L0_CONFIG VERA_BASE + 0x0D
|
||||
#define VERA_L0_MAPBASE VERA_BASE + 0x0E
|
||||
#define VERA_L0_TILEBASE VERA_BASE + 0x0F
|
||||
#define VERA_L0_HSCROLL_L VERA_BASE + 0x10
|
||||
#define VERA_L0_HSCROLL_H VERA_BASE + 0x11
|
||||
#define VERA_L0_VSCROLL_L VERA_BASE + 0x12
|
||||
#define VERA_L0_VSCROLL_H VERA_BASE + 0x13
|
||||
|
||||
// Layer 1
|
||||
#define VERA_L1_CONFIG VERA_BASE + 0x14
|
||||
#define VERA_L1_MAPBASE VERA_BASE + 0x15
|
||||
#define VERA_L1_TILEBASE VERA_BASE + 0x16
|
||||
#define VERA_L1_HSCROLL_L VERA_BASE + 0x17
|
||||
#define VERA_L1_HSCROLL_H VERA_BASE + 0x18
|
||||
#define VERA_L1_VSCROLL_L VERA_BASE + 0x19
|
||||
#define VERA_L1_VSCROLL_H VERA_BASE + 0x1A
|
||||
|
||||
// Audio
|
||||
#define VERA_AUDIO_CTRL VERA_BASE + 0x1B
|
||||
#define VERA_AUDIO_RATE VERA_BASE + 0x1C
|
||||
#define VERA_AUDIO_DATA VERA_BASE + 0x1D
|
||||
|
||||
// SPI (Unused in prototype four!)
|
||||
#define VERA_SPI_DATA VERA_BASE + 0x1E
|
||||
#define VERA_SPI_CTRL VERA_BASE + 0x1F
|
||||
|
||||
// VRAM layout
|
||||
#define TEXT_CONSOLE_TILES 0x000800
|
||||
#define TEXT_CONSOLE0_VRAM 0x001800 // Runs up to 0x5800
|
||||
#define TEXT_CONSOLE_SPRITE_BITMAPS 0x005800
|
||||
#define VERA_PSG_BASE 0x01F9C0
|
||||
#define VERA_PALETTE_BASE 0x01FA00
|
||||
#define VERA_SPRITE_ATTR_BASE 0x01FC00
|
|
@ -0,0 +1,129 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// boot/w65c265s.h
|
||||
// Assembly defines for the W65C265S chip
|
||||
//
|
||||
// Copyright © 2024 Kyle J Cardoza <Kyle.Cardoza@icloud.com>
|
||||
|
||||
|
||||
#define PD0 0x00DF00
|
||||
#define PD1 0x00DF01
|
||||
#define PD2 0x00DF02
|
||||
#define PD3 0x00DF03
|
||||
#define PD4 0x00DF20
|
||||
#define PD5 0x00DF21
|
||||
#define PD6 0x00DF22
|
||||
#define PD7 0x00DF23
|
||||
|
||||
#define PDD0 0x00DF04
|
||||
#define PDD1 0x00DF05
|
||||
#define PDD2 0x00DF06
|
||||
#define PDD3 0x00DF07
|
||||
#define PDD4 0x00DF24
|
||||
#define PDD5 0x00DF25
|
||||
#define PDD6 0x00DF26
|
||||
|
||||
#define PCS7 0x00DF27
|
||||
#define BCR 0x00DF40
|
||||
#define SSCR 0x00DF41
|
||||
|
||||
#define TCR 0x00DF42
|
||||
#define TER 0x00DF43
|
||||
#define TIFR 0x00DF44
|
||||
#define EIFR 0x00DF45
|
||||
#define TIER 0x00DF46
|
||||
#define EIER 0x00DF47
|
||||
#define UIFR 0x00DF48
|
||||
#define UIER 0x00DF49
|
||||
|
||||
#define T0LL 0x00DF50
|
||||
#define T0LH 0x00DF51
|
||||
#define T1LL 0x00DF52
|
||||
#define T1LH 0x00DF53
|
||||
#define T2LL 0x00DF54
|
||||
#define T2LH 0x00DF55
|
||||
#define T3LL 0x00DF56
|
||||
#define T3LH 0x00DF57
|
||||
#define T4LL 0x00DF58
|
||||
#define T4LH 0x00DF59
|
||||
#define T5LL 0x00DF5A
|
||||
#define T5LH 0x00DF5B
|
||||
#define T6LL 0x00DF5C
|
||||
#define T6LH 0x00DF5D
|
||||
#define T7LL 0x00DF5E
|
||||
#define T7LH 0x00DF5F
|
||||
#define T0CL 0x00DF60
|
||||
#define T0CH 0x00DF61
|
||||
#define T1CL 0x00DF62
|
||||
#define T1CH 0x00DF63
|
||||
#define T2CL 0x00DF64
|
||||
#define T2CH 0x00DF65
|
||||
#define T3CL 0x00DF66
|
||||
#define T3CH 0x00DF67
|
||||
#define T4CL 0x00DF68
|
||||
#define T4CH 0x00DF69
|
||||
#define T5CL 0x00DF6A
|
||||
#define T5CH 0x00DF6B
|
||||
#define T6CL 0x00DF6C
|
||||
#define T6CH 0x00DF6D
|
||||
#define T7CL 0x00DF6E
|
||||
#define T7CH 0x00DF6F
|
||||
|
||||
#define ACSR0 0x00DF70
|
||||
#define ARTD0 0x00DF71
|
||||
#define ACSR1 0x00DF72
|
||||
#define ARTD1 0x00DF73
|
||||
#define ACSR2 0x00DF74
|
||||
#define ARTD2 0x00DF75
|
||||
#define ACSR3 0x00DF76
|
||||
#define ARTD3 0x00DF77
|
||||
|
||||
#define PIBFR 0x00DF78
|
||||
#define PIBER 0x00DF79
|
||||
#define PIR2 0x00DF7A
|
||||
#define PIR3 0x00DF7B
|
||||
#define PIR4 0x00DF7C
|
||||
#define PIR5 0x00DF7D
|
||||
#define PIR6 0x00DF7E
|
||||
#define PIR7 0x00DF7F
|
||||
|
||||
; Enable the 512 bytes of on-CPU SRAM from 0x000000-0001FF
|
||||
w65c265s_sram_on .macro
|
||||
lda #0b00000100
|
||||
trb SSCR
|
||||
.endm
|
||||
|
||||
w65c265s_sram_off .macro
|
||||
lda #0b00000100
|
||||
tsb SSCR
|
||||
.endm
|
||||
|
||||
; Disable the on-CPU ROM
|
||||
w65c265s_rom_off .macro
|
||||
lda #1 << 7
|
||||
tsb BCR
|
||||
.endm
|
||||
|
||||
; Enable the on-CPU ROM
|
||||
w65c265s_rom_on .macro
|
||||
lda #1 << 7
|
||||
trb BCR
|
||||
.endm
|
||||
|
||||
; Start FCLK
|
||||
fclk_start .macro
|
||||
lda #0b00000001
|
||||
tsb SSCR
|
||||
.endm
|
||||
|
||||
; Stop FCLK
|
||||
fclk_stop .macro
|
||||
lda #0b00000001
|
||||
trb SSCR
|
||||
.endm
|
||||
|
||||
; Select FCLK as the clock source
|
||||
fclk_select .macro
|
||||
lda #0b11111010
|
||||
tsb SSCR
|
||||
.endm
|
|
@ -0,0 +1,9 @@
|
|||
//*****************************************************************************
|
||||
// 65X-DOS
|
||||
//
|
||||
// include/config.h
|
||||
//*****************************************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
Copyright © 2024 Kyle J Cardoza
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,15 @@
|
|||
# Sentinel 65X ROM Firmware
|
||||
|
||||
This source tree builds the 512KB .bin file used to burn the system ROM
|
||||
for Sentinel 65X. It consists of several modules:
|
||||
|
||||
- boot: initial boot code
|
||||
- irq: interrupt handler vectors and trampolines
|
||||
- bios: essential hardware driver code and IRQ handler implementations
|
||||
- bdos: core operating system
|
||||
|
||||
In future, more modules are planned:
|
||||
|
||||
- A 65816 macro assembler
|
||||
- A text editor
|
||||
- Your idea here!
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,35 @@
|
|||
FatFs License
|
||||
|
||||
FatFs has being developped as a personal project of the author, ChaN. It is
|
||||
free from the code anyone else wrote at current release. Following code block
|
||||
shows a copy of the FatFs license document that heading the source files.
|
||||
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem Module Rx.xx /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 20xx, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
/ that the following condition is met:
|
||||
/
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
Therefore FatFs license is one of the BSD-style licenses, but there is a
|
||||
significant feature. FatFs is mainly intended for embedded systems. In order to
|
||||
extend the usability for commercial products, the redistributions of FatFs in
|
||||
binary form, such as embedded code, binary library and any forms without source
|
||||
code, do not need to include about FatFs in the documentations. This is
|
||||
equivalent to the 1-clause BSD license. Of course FatFs is compatible with
|
||||
the most of open source software licenses include GNU GPL. When you
|
||||
redistribute the FatFs source code with changes or create a fork, the license
|
||||
can also be changed to GNU GPL, BSD-style license or any open source software
|
||||
license that not conflict with FatFs license.
|
|
@ -0,0 +1,470 @@
|
|||
/*------------------------------------------------------------------------/
|
||||
/ Foolproof MMCv3/SDv1/SDv2 (in SPI mode) control module
|
||||
/-------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2019, ChaN, all right reserved.
|
||||
/
|
||||
/ * This software is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/
|
||||
/-------------------------------------------------------------------------/
|
||||
Features and Limitations:
|
||||
|
||||
* No Media Change Detection
|
||||
Application program needs to perform a f_mount() after media change.
|
||||
|
||||
/-------------------------------------------------------------------------*/
|
||||
|
||||
#include "kernel/drivers/fatfs/ff.h" /* Obtains integer types for FatFs */
|
||||
#include "kernel/drivers/fatfs/diskio.h" /* Common include file for FatFs and disk I/O layer */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/* Platform dependent macros and functions needed to be modified */
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------*/
|
||||
/* User Provided RTC Function for FatFs module */
|
||||
/*---------------------------------------------------------*/
|
||||
/* This is a real time clock service to be called from */
|
||||
/* FatFs module. Any valid time must be returned even if */
|
||||
/* the system does not support an RTC. */
|
||||
/* This function is not required in read-only cfg. */
|
||||
|
||||
// FIXME: Make this use the system RTC.
|
||||
DWORD get_fattime (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: Make this delay using a system timer.
|
||||
static void
|
||||
dly_us (int n)
|
||||
{
|
||||
(void) n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Module Private Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* MMC/SD command (SPI mode) */
|
||||
#define CMD0 (0) /* GO_IDLE_STATE */
|
||||
#define CMD1 (1) /* SEND_OP_COND */
|
||||
#define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */
|
||||
#define CMD8 (8) /* SEND_IF_COND */
|
||||
#define CMD9 (9) /* SEND_CSD */
|
||||
#define CMD10 (10) /* SEND_CID */
|
||||
#define CMD12 (12) /* STOP_TRANSMISSION */
|
||||
#define CMD13 (13) /* SEND_STATUS */
|
||||
#define ACMD13 (0x80+13) /* SD_STATUS (SDC) */
|
||||
#define CMD16 (16) /* SET_BLOCKLEN */
|
||||
#define CMD17 (17) /* READ_SINGLE_BLOCK */
|
||||
#define CMD18 (18) /* READ_MULTIPLE_BLOCK */
|
||||
#define CMD23 (23) /* SET_BLOCK_COUNT */
|
||||
#define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
|
||||
#define CMD24 (24) /* WRITE_BLOCK */
|
||||
#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
|
||||
#define CMD32 (32) /* ERASE_ER_BLK_START */
|
||||
#define CMD33 (33) /* ERASE_ER_BLK_END */
|
||||
#define CMD38 (38) /* ERASE */
|
||||
#define CMD55 (55) /* APP_CMD */
|
||||
#define CMD58 (58) /* READ_OCR */
|
||||
|
||||
|
||||
static
|
||||
DSTATUS Stat = STA_NOINIT; /* Disk status */
|
||||
|
||||
static
|
||||
BYTE CardType; /* b0:MMC, b1:SDv1, b2:SDv2, b3:Block addressing */
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Transmit bytes to the card */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
// FIXME: Make this use VERA.
|
||||
static
|
||||
void xmit_mmc (const BYTE* buff, UINT count)
|
||||
{
|
||||
(void) buff;
|
||||
(void) count;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Receive bytes from the card */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
// FIXME: Make this use VERA.
|
||||
static
|
||||
void rcvr_mmc (BYTE *buff, UINT count)
|
||||
{
|
||||
(void) buff;
|
||||
(void) count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Wait for card ready */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
int wait_ready (void) /* 1:OK, 0:Timeout */
|
||||
{
|
||||
BYTE d;
|
||||
UINT tmr;
|
||||
|
||||
|
||||
for (tmr = 5000; tmr; tmr--) { /* Wait for ready in timeout of 500ms */
|
||||
rcvr_mmc(&d, 1);
|
||||
if (d == 0xFF) break;
|
||||
dly_us(100);
|
||||
}
|
||||
|
||||
return tmr ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Deselect the card and release SPI bus */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
// FIXME: Make this use VERA.
|
||||
static
|
||||
void deselect (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Select the card and wait for ready */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
// FIXME: Make this use VERA.
|
||||
static
|
||||
int select (void) /* 1:OK, 0:Timeout */
|
||||
{
|
||||
return 0; /* Failed */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Receive a data packet from the card */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
int rcvr_datablock ( /* 1:OK, 0:Failed */
|
||||
BYTE *buff, /* Data buffer to store received data */
|
||||
UINT btr /* Byte count */
|
||||
)
|
||||
{
|
||||
BYTE d[2];
|
||||
UINT tmr;
|
||||
|
||||
|
||||
for (tmr = 1000; tmr; tmr--) { /* Wait for data packet in timeout of 100ms */
|
||||
rcvr_mmc(d, 1);
|
||||
if (d[0] != 0xFF) break;
|
||||
dly_us(100);
|
||||
}
|
||||
if (d[0] != 0xFE) return 0; /* If not valid data token, return with error */
|
||||
|
||||
rcvr_mmc(buff, btr); /* Receive the data block into buffer */
|
||||
rcvr_mmc(d, 2); /* Discard CRC */
|
||||
|
||||
return 1; /* Return with success */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Send a data packet to the card */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
int xmit_datablock ( /* 1:OK, 0:Failed */
|
||||
const BYTE *buff, /* 512 byte data block to be transmitted */
|
||||
BYTE token /* Data/Stop token */
|
||||
)
|
||||
{
|
||||
BYTE d[2];
|
||||
|
||||
|
||||
if (!wait_ready()) return 0;
|
||||
|
||||
d[0] = token;
|
||||
xmit_mmc(d, 1); /* Xmit a token */
|
||||
if (token != 0xFD) { /* Is it data token? */
|
||||
xmit_mmc(buff, 512); /* Xmit the 512 byte data block to MMC */
|
||||
rcvr_mmc(d, 2); /* Xmit dummy CRC (0xFF,0xFF) */
|
||||
rcvr_mmc(d, 1); /* Receive data response */
|
||||
if ((d[0] & 0x1F) != 0x05) /* If not accepted, return with error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Send a command packet to the card */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
static
|
||||
BYTE send_cmd ( /* Returns command response (bit7==1:Send failed)*/
|
||||
BYTE cmd, /* Command byte */
|
||||
DWORD arg /* Argument */
|
||||
)
|
||||
{
|
||||
BYTE n, d, buf[6];
|
||||
|
||||
|
||||
if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */
|
||||
cmd &= 0x7F;
|
||||
n = send_cmd(CMD55, 0);
|
||||
if (n > 1) return n;
|
||||
}
|
||||
|
||||
/* Select the card and wait for ready except to stop multiple block read */
|
||||
if (cmd != CMD12) {
|
||||
deselect();
|
||||
if (!select()) return 0xFF;
|
||||
}
|
||||
|
||||
/* Send a command packet */
|
||||
buf[0] = 0x40 | cmd; /* Start + Command index */
|
||||
buf[1] = (BYTE)(arg >> 24); /* Argument[31..24] */
|
||||
buf[2] = (BYTE)(arg >> 16); /* Argument[23..16] */
|
||||
buf[3] = (BYTE)(arg >> 8); /* Argument[15..8] */
|
||||
buf[4] = (BYTE)arg; /* Argument[7..0] */
|
||||
n = 0x01; /* Dummy CRC + Stop */
|
||||
if (cmd == CMD0) n = 0x95; /* (valid CRC for CMD0(0)) */
|
||||
if (cmd == CMD8) n = 0x87; /* (valid CRC for CMD8(0x1AA)) */
|
||||
buf[5] = n;
|
||||
xmit_mmc(buf, 6);
|
||||
|
||||
/* Receive command response */
|
||||
if (cmd == CMD12) rcvr_mmc(&d, 1); /* Skip a stuff byte when stop reading */
|
||||
n = 10; /* Wait for a valid response in timeout of 10 attempts */
|
||||
do
|
||||
rcvr_mmc(&d, 1);
|
||||
while ((d & 0x80) && --n);
|
||||
|
||||
return d; /* Return with the response value */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Public Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Get Disk Status */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE drv /* Drive number (always 0) */
|
||||
)
|
||||
{
|
||||
if (drv) return STA_NOINIT;
|
||||
|
||||
return Stat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Initialize Disk Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE drv /* Physical drive nmuber (0) */
|
||||
)
|
||||
{
|
||||
BYTE n, ty, cmd, buf[4];
|
||||
UINT tmr;
|
||||
DSTATUS s;
|
||||
|
||||
|
||||
if (drv) return RES_NOTRDY;
|
||||
|
||||
dly_us(10000); /* 10ms */
|
||||
|
||||
for (n = 10; n; n--) rcvr_mmc(buf, 1); /* Apply 80 dummy clocks and the card gets ready to receive command */
|
||||
|
||||
ty = 0;
|
||||
if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
|
||||
if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2? */
|
||||
rcvr_mmc(buf, 4); /* Get trailing return value of R7 resp */
|
||||
if (buf[2] == 0x01 && buf[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
|
||||
for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state (ACMD41 with HCS bit) */
|
||||
if (send_cmd(ACMD41, 1UL << 30) == 0) break;
|
||||
dly_us(1000);
|
||||
}
|
||||
if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
|
||||
rcvr_mmc(buf, 4);
|
||||
ty = (buf[0] & 0x40) ? CT_SDC2 | CT_BLOCK : CT_SDC2; /* SDv2+ */
|
||||
}
|
||||
}
|
||||
} else { /* SDv1 or MMCv3 */
|
||||
if (send_cmd(ACMD41, 0) <= 1) {
|
||||
ty = CT_SDC2; cmd = ACMD41; /* SDv1 */
|
||||
} else {
|
||||
ty = CT_MMC3; cmd = CMD1; /* MMCv3 */
|
||||
}
|
||||
for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state */
|
||||
if (send_cmd(cmd, 0) == 0) break;
|
||||
dly_us(1000);
|
||||
}
|
||||
if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */
|
||||
ty = 0;
|
||||
}
|
||||
}
|
||||
CardType = ty;
|
||||
s = ty ? 0 : STA_NOINIT;
|
||||
Stat = s;
|
||||
|
||||
deselect();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
BYTE *buff, /* Pointer to the data buffer to store read data */
|
||||
LBA_t sector, /* Start sector number (LBA) */
|
||||
UINT count /* Sector count (1..128) */
|
||||
)
|
||||
{
|
||||
BYTE cmd;
|
||||
DWORD sect = (DWORD)sector;
|
||||
|
||||
|
||||
if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY;
|
||||
if (!(CardType & CT_BLOCK)) sect *= 512; /* Convert LBA to byte address if needed */
|
||||
|
||||
cmd = count > 1 ? CMD18 : CMD17; /* READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */
|
||||
if (send_cmd(cmd, sect) == 0) {
|
||||
do {
|
||||
if (!rcvr_datablock(buff, 512)) break;
|
||||
buff += 512;
|
||||
} while (--count);
|
||||
if (cmd == CMD18) send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
|
||||
}
|
||||
deselect();
|
||||
|
||||
return count ? RES_ERROR : RES_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_write (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
const BYTE *buff, /* Pointer to the data to be written */
|
||||
LBA_t sector, /* Start sector number (LBA) */
|
||||
UINT count /* Sector count (1..128) */
|
||||
)
|
||||
{
|
||||
DWORD sect = (DWORD)sector;
|
||||
|
||||
|
||||
if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY;
|
||||
//if (!(CardType & CT_BLOCK)) sect *= 512; /* Convert LBA to byte address if needed */
|
||||
|
||||
if (count == 1) { /* Single block write */
|
||||
if ((send_cmd(CMD24, sect) == 0) /* WRITE_BLOCK */
|
||||
&& xmit_datablock(buff, 0xFE))
|
||||
count = 0;
|
||||
}
|
||||
else { /* Multiple block write */
|
||||
if (CardType & CT_SDC) send_cmd(ACMD23, count);
|
||||
if (send_cmd(CMD25, sect) == 0) { /* WRITE_MULTIPLE_BLOCK */
|
||||
do {
|
||||
if (!xmit_datablock(buff, 0xFC)) break;
|
||||
buff += 512;
|
||||
} while (--count);
|
||||
if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
deselect();
|
||||
|
||||
return count ? RES_ERROR : RES_OK;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_ioctl (
|
||||
BYTE drv, /* Physical drive nmuber (0) */
|
||||
BYTE ctrl, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
BYTE n, csd[16];
|
||||
DWORD cs;
|
||||
|
||||
|
||||
if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY; /* Check if card is in the socket */
|
||||
|
||||
res = RES_ERROR;
|
||||
switch (ctrl) {
|
||||
case CTRL_SYNC : /* Make sure that no pending write process */
|
||||
if (select()) res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
|
||||
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
|
||||
if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
|
||||
cs = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
|
||||
*(LBA_t*)buff = cs << 10;
|
||||
} else { /* SDC ver 1.XX or MMC */
|
||||
n = (BYTE)((csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2);
|
||||
cs = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
|
||||
*(LBA_t*)buff = cs << (n - 9);
|
||||
}
|
||||
res = RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
|
||||
*(DWORD*)buff = 128;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
res = RES_PARERR;
|
||||
}
|
||||
|
||||
deselect();
|
||||
|
||||
return res;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,207 @@
|
|||
/*------------------------------------------------------------------------*/
|
||||
/* A Sample Code of User Provided OS Dependent Functions for FatFs */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#include "kernel/drivers/fatfs/ff.h"
|
||||
|
||||
|
||||
#if FF_USE_LFN == 3 /* Use dynamic memory allocation */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Allocate/Free a Memory Block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdlib.h" /* with POSIX API */
|
||||
|
||||
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return malloc((size_t)msize); /* Allocate a new memory block */
|
||||
}
|
||||
|
||||
|
||||
void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free (no effect if null) */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Free the memory block */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if FF_FS_REENTRANT /* Mutal exclusion */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Definitions of Mutex */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#define OS_TYPE 0 /* 0:Win32, 1:uITRON4.0, 2:uC/OS-II, 3:FreeRTOS, 4:CMSIS-RTOS */
|
||||
|
||||
|
||||
#if OS_TYPE == 0 /* Win32 */
|
||||
#include <windows.h>
|
||||
static HANDLE Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */
|
||||
|
||||
#elif OS_TYPE == 1 /* uITRON */
|
||||
#include "itron.h"
|
||||
#include "kernel.h"
|
||||
static mtxid Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */
|
||||
|
||||
#elif OS_TYPE == 2 /* uc/OS-II */
|
||||
#include "includes.h"
|
||||
static OS_EVENT *Mutex[FF_VOLUMES + 1]; /* Table of mutex pinter */
|
||||
|
||||
#elif OS_TYPE == 3 /* FreeRTOS */
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
static SemaphoreHandle_t Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */
|
||||
|
||||
#elif OS_TYPE == 4 /* CMSIS-RTOS */
|
||||
#include "cmsis_os.h"
|
||||
static osMutexId Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Mutex */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount function to create a new mutex
|
||||
/ or semaphore for the volume. When a 0 is returned, the f_mount function
|
||||
/ fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_mutex_create ( /* Returns 1:Function succeeded or 0:Could not create the mutex */
|
||||
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
|
||||
)
|
||||
{
|
||||
#if OS_TYPE == 0 /* Win32 */
|
||||
Mutex[vol] = CreateMutex(NULL, FALSE, NULL);
|
||||
return (int)(Mutex[vol] != INVALID_HANDLE_VALUE);
|
||||
|
||||
#elif OS_TYPE == 1 /* uITRON */
|
||||
T_CMTX cmtx = {TA_TPRI,1};
|
||||
|
||||
Mutex[vol] = acre_mtx(&cmtx);
|
||||
return (int)(Mutex[vol] > 0);
|
||||
|
||||
#elif OS_TYPE == 2 /* uC/OS-II */
|
||||
OS_ERR err;
|
||||
|
||||
Mutex[vol] = OSMutexCreate(0, &err);
|
||||
return (int)(err == OS_NO_ERR);
|
||||
|
||||
#elif OS_TYPE == 3 /* FreeRTOS */
|
||||
Mutex[vol] = xSemaphoreCreateMutex();
|
||||
return (int)(Mutex[vol] != NULL);
|
||||
|
||||
#elif OS_TYPE == 4 /* CMSIS-RTOS */
|
||||
osMutexDef(cmsis_os_mutex);
|
||||
|
||||
Mutex[vol] = osMutexCreate(osMutex(cmsis_os_mutex));
|
||||
return (int)(Mutex[vol] != NULL);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Delete a Mutex */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount function to delete a mutex or
|
||||
/ semaphore of the volume created with ff_mutex_create function.
|
||||
*/
|
||||
|
||||
void ff_mutex_delete ( /* Returns 1:Function succeeded or 0:Could not delete due to an error */
|
||||
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
|
||||
)
|
||||
{
|
||||
#if OS_TYPE == 0 /* Win32 */
|
||||
CloseHandle(Mutex[vol]);
|
||||
|
||||
#elif OS_TYPE == 1 /* uITRON */
|
||||
del_mtx(Mutex[vol]);
|
||||
|
||||
#elif OS_TYPE == 2 /* uC/OS-II */
|
||||
OS_ERR err;
|
||||
|
||||
OSMutexDel(Mutex[vol], OS_DEL_ALWAYS, &err);
|
||||
|
||||
#elif OS_TYPE == 3 /* FreeRTOS */
|
||||
vSemaphoreDelete(Mutex[vol]);
|
||||
|
||||
#elif OS_TYPE == 4 /* CMSIS-RTOS */
|
||||
osMutexDelete(Mutex[vol]);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Request a Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on enter file functions to lock the volume.
|
||||
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||
*/
|
||||
|
||||
int ff_mutex_take ( /* Returns 1:Succeeded or 0:Timeout */
|
||||
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
|
||||
)
|
||||
{
|
||||
#if OS_TYPE == 0 /* Win32 */
|
||||
return (int)(WaitForSingleObject(Mutex[vol], FF_FS_TIMEOUT) == WAIT_OBJECT_0);
|
||||
|
||||
#elif OS_TYPE == 1 /* uITRON */
|
||||
return (int)(tloc_mtx(Mutex[vol], FF_FS_TIMEOUT) == E_OK);
|
||||
|
||||
#elif OS_TYPE == 2 /* uC/OS-II */
|
||||
OS_ERR err;
|
||||
|
||||
OSMutexPend(Mutex[vol], FF_FS_TIMEOUT, &err));
|
||||
return (int)(err == OS_NO_ERR);
|
||||
|
||||
#elif OS_TYPE == 3 /* FreeRTOS */
|
||||
return (int)(xSemaphoreTake(Mutex[vol], FF_FS_TIMEOUT) == pdTRUE);
|
||||
|
||||
#elif OS_TYPE == 4 /* CMSIS-RTOS */
|
||||
return (int)(osMutexWait(Mutex[vol], FF_FS_TIMEOUT) == osOK);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release a Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leave file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_mutex_give (
|
||||
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
|
||||
)
|
||||
{
|
||||
#if OS_TYPE == 0 /* Win32 */
|
||||
ReleaseMutex(Mutex[vol]);
|
||||
|
||||
#elif OS_TYPE == 1 /* uITRON */
|
||||
unl_mtx(Mutex[vol]);
|
||||
|
||||
#elif OS_TYPE == 2 /* uC/OS-II */
|
||||
OSMutexPost(Mutex[vol]);
|
||||
|
||||
#elif OS_TYPE == 3 /* FreeRTOS */
|
||||
xSemaphoreGive(Mutex[vol]);
|
||||
|
||||
#elif OS_TYPE == 4 /* CMSIS-RTOS */
|
||||
osMutexRelease(Mutex[vol]);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* FF_FS_REENTRANT */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,13 @@
|
|||
//*****************************************************************************
|
||||
// 65X-DOS
|
||||
//
|
||||
// src/bdos/main.c
|
||||
//*****************************************************************************
|
||||
|
||||
#include "config.h"
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
for (;;) {}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// bios/main.c
|
||||
// Sentinel 65X BIOS: main() function
|
||||
//
|
||||
// Copyright © 2024 Kyle J Cardoza <Kyle.Cardoza@icloud.com>
|
||||
|
||||
void main(void) {
|
||||
for (;;) {}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
;;; Startup variant, change attribute value if you make your own
|
||||
.rtmodel cstartup,"sentinel65x"
|
||||
|
||||
.rtmodel version, "1"
|
||||
.rtmodel core, "*"
|
||||
|
||||
.section stack
|
||||
.section cstack
|
||||
.section heap
|
||||
|
||||
.extern main, exit
|
||||
.extern _Dp, _Vfp
|
||||
.extern _DirectPageStart
|
||||
|
||||
#ifndef __CALYPSI_DATA_MODEL_SMALL__
|
||||
.extern _NearBaseAddress
|
||||
#endif
|
||||
|
||||
#include "bios/macros.h"
|
||||
|
||||
;;; ***************************************************************************
|
||||
;;;
|
||||
;;; __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.
|
||||
;;;
|
||||
;;; ***************************************************************************
|
||||
|
||||
.section code, noreorder
|
||||
.pubweak __program_root_section
|
||||
__program_root_section:
|
||||
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
|
||||
lda ##.word2 _NearBaseAddress
|
||||
stz dp:.tiny(_Vfp+2)
|
||||
xba ; A upper half = data bank
|
||||
pha
|
||||
plb ; pop 8 dummy
|
||||
plb ; set data bank
|
||||
|
||||
;;; **** Initialize heap if needed.
|
||||
.section code, noroot, noreorder
|
||||
.pubweak __call_heap_initialize
|
||||
.extern __heap_initialize, __default_heap
|
||||
__call_heap_initialize:
|
||||
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)
|
||||
call __heap_initialize
|
||||
|
||||
.section code, root, noreorder
|
||||
lda ##0 ; argc = 0
|
||||
call main
|
||||
jump exit
|
|
@ -0,0 +1,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// bios/stubs.c
|
||||
// Stub functions for Calypsi's C library
|
||||
//
|
||||
// Copyright © 2024 Kyle J Cardoza <Kyle.Cardoza@icloud.com>
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
//; SPDX-License-Identifier: MIT
|
||||
//;
|
||||
//; bios/irq_trampoline.s
|
||||
//; IRQ trampoline code for Sentinel 65X
|
||||
//;
|
||||
//; The two sections below are visible in ROM when the CPU's
|
||||
//; on-chip ROM is disabled. They must be copied to RAM if
|
||||
//; on-board ROM is to be disabled.
|
||||
//;
|
||||
//;
|
||||
//; Copyright © 2024 Kyle J Cardoza <Kyle.Cardoza@icloud.com>
|
||||
|
||||
; This section gets copied to 0x00F000
|
||||
.section irq_trampolines
|
||||
|
||||
reserved_irq:
|
||||
rti
|
||||
|
||||
timer0_irq:
|
||||
rti
|
||||
|
||||
timer1_irq:
|
||||
rti
|
||||
|
||||
timer2_irq:
|
||||
rti
|
||||
|
||||
timer3_irq:
|
||||
rti
|
||||
|
||||
timer4_irq:
|
||||
rti
|
||||
|
||||
timer5_irq:
|
||||
rti
|
||||
|
||||
timer6_irq:
|
||||
rti
|
||||
|
||||
timer7_irq:
|
||||
rti
|
||||
|
||||
pe56_irq:
|
||||
rti
|
||||
|
||||
ne57_irq:
|
||||
rti
|
||||
|
||||
pe60_irq:
|
||||
rti
|
||||
|
||||
pe62_irq:
|
||||
rti
|
||||
|
||||
ne64_irq:
|
||||
rti
|
||||
|
||||
ne66_irq:
|
||||
rti
|
||||
|
||||
pib_irq:
|
||||
rti
|
||||
|
||||
level_irq:
|
||||
rti
|
||||
|
||||
uart_0_rx_irq:
|
||||
rti
|
||||
|
||||
uart_0_tx_irq:
|
||||
rti
|
||||
|
||||
uart_1_rx_irq:
|
||||
rti
|
||||
|
||||
uart_1_tx_irq:
|
||||
rti
|
||||
|
||||
uart_2_rx_irq:
|
||||
rti
|
||||
|
||||
uart_2_tx_irq:
|
||||
rti
|
||||
|
||||
uart_3_rx_irq:
|
||||
rti
|
||||
|
||||
uart_3_tx_irq:
|
||||
rti
|
||||
|
||||
cop_irq:
|
||||
rti
|
||||
|
||||
brk_irq:
|
||||
rti
|
||||
|
||||
abort_irq:
|
||||
rti
|
||||
|
||||
nmi_irq:
|
||||
rti
|
||||
|
||||
; This section gets copied to 0x00FF80
|
||||
.section irq_vectors
|
||||
; Native mode IRQ vectors
|
||||
.word .word0(timer0_irq)
|
||||
.word .word0(timer1_irq)
|
||||
.word .word0(timer2_irq)
|
||||
.word .word0(timer3_irq)
|
||||
.word .word0(timer4_irq)
|
||||
.word .word0(timer5_irq)
|
||||
.word .word0(timer6_irq)
|
||||
.word .word0(timer7_irq)
|
||||
.word .word0(pe56_irq)
|
||||
.word .word0(ne57_irq)
|
||||
.word .word0(pe60_irq)
|
||||
.word .word0(pe62_irq)
|
||||
.word .word0(ne64_irq)
|
||||
.word .word0(ne66_irq)
|
||||
.word .word0(pib_irq)
|
||||
.word .word0(level_irq)
|
||||
.word .word0(uart_0_rx_irq)
|
||||
.word .word0(uart_0_tx_irq)
|
||||
.word .word0(uart_1_rx_irq)
|
||||
.word .word0(uart_1_tx_irq)
|
||||
.word .word0(uart_2_rx_irq)
|
||||
.word .word0(uart_2_tx_irq)
|
||||
.word .word0(uart_3_rx_irq)
|
||||
.word .word0(uart_3_tx_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(cop_irq)
|
||||
.word .word0(brk_irq)
|
||||
.word .word0(abort_irq)
|
||||
.word .word0(nmi_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
|
||||
; Emulation mode is not supported right now.
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
||||
.word .word0(reserved_irq)
|
|
@ -0,0 +1,95 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// bios/stubs.c
|
||||
// Stub functions for Calypsi's C library
|
||||
//
|
||||
// Copyright © 2024 Kyle J Cardoza <Kyle.Cardoza@icloud.com>
|
||||
|
||||
#include "calypsi/stubs.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
int _Stub_putchar(int ch)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _Stub_puts(const char *str)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _Stub_raise(int signo)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _Stub_open(const char *path, int oflag, ...)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _Stub_close(int fd)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _Stub_fcntl(int fd, int command, ...)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _Stub_access(const char *path, int mode)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
long _Stub_lseek(int fd, long offset, int whence)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _Stub_fsetpos(int fd, const fpos_t *pos)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t _Stub_read(int fd, void *buf, size_t count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t _Stub_write(int fd, const void *buf, size_t count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _Stub_rename(const char *oldpath, const char *newpath)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _Stub_remove(const char *path)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
__noreturn_function
|
||||
void _Stub_exit(int exitCode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char** _Stub_environ(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__noreturn_function
|
||||
void _Stub_assert()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
|
@ -0,0 +1,53 @@
|
|||
//; SPDX-License-Identifier: MIT
|
||||
//;
|
||||
//; boot/boot.s
|
||||
//; Boot code for Sentinel 65X
|
||||
//;
|
||||
//; Copyright © 2024 Kyle J Cardoza <Kyle.Cardoza@icloud.com>
|
||||
|
||||
#include "boot/sentinel65x.h"
|
||||
|
||||
.section code, noreorder
|
||||
.pubweak __program_root_section
|
||||
__program_root_section:
|
||||
.asciz "WDC"
|
||||
w65c265s_init:
|
||||
// Disable interrupts
|
||||
sei
|
||||
stz UIER
|
||||
stz TIER
|
||||
stz EIER
|
||||
short_a
|
||||
long_i
|
||||
|
||||
// We reset the VERA at boot. So P4.2 is an output, held
|
||||
// low until later in the boot sequence.
|
||||
lda #1 << 2
|
||||
trb PD4
|
||||
tsb PDD4
|
||||
|
||||
// Now we delay a while.
|
||||
ldy ##0x0FFF
|
||||
delay_y
|
||||
dey
|
||||
bne delay_y
|
||||
|
||||
// Set stack to $001FF
|
||||
ldx ##0x01FF
|
||||
txs
|
||||
|
||||
// Set data bank to 0
|
||||
lda #0
|
||||
pha
|
||||
plb
|
||||
|
||||
// Set direct page to $0000
|
||||
pea #0x0000
|
||||
pld
|
||||
|
||||
// Enable all the in-use chip select lines.
|
||||
lda #0b11110011
|
||||
sta PCS7
|
||||
|
||||
// And we are booted enough to jump to high ROM.
|
||||
jmp 0xC00000
|
Loading…
Reference in New Issue