Delete everything

This commit is contained in:
Byron Lathi
2024-03-02 20:10:50 -08:00
parent 273484b994
commit 0a0394ae33
293 changed files with 1 additions and 94765 deletions

58
sw/.gitignore vendored
View File

@@ -1,58 +0,0 @@
# Prerequisites
*.d
# Object files
*.o
*.o65
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
lists/
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.bin
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# Filesystem Images
*.fat

View File

@@ -1,23 +0,0 @@
.PHONY: all install bios kernel clean distclean
all: toolchain bios kernel
install: all
sh script/format_disk.sh
sh script/copy_files.sh
toolchain:
@$(MAKE) -j4 -C cc65
bios:
@$(MAKE) -C bios
kernel:
@$(MAKE) -C kernel
distclean: clean
@$(MAKE) -C cc65 --no-print-directory $@
clean:
@$(MAKE) -C bios --no-print-directory $@
@$(MAKE) -C kernel --no-print-directory $@

View File

@@ -1,58 +0,0 @@
CC=../cc65/bin/cl65
CFLAGS=-T -t none -I. --cpu "65C02" -DRTL_SIM
LDFLAGS=-C link.ld -m $(NAME).map
FSDIR=$(REPO_TOP)/sw/fsdir
NAME=bios
BIN=$(NAME).bin
HEX=$(NAME).hex
FPGA_IMG=$(REPO_TOP)/hw/efinix_fpga/init_hex.mem
EFX_RUN=/home/byron/Software/efinity/2023.1/scripts/efx_run.py
EFX_PRJ=/home/byron/Projects/super6502/hw/efinix_fpga/super6502.xml
LISTS=lists
TESTS=tests
SRCS=$(wildcard *.s) $(wildcard *.c)
SRCS+=$(filter-out $(wildcard tests/*), $(wildcard **/*.s)) $(filter-out $(wildcard tests/*), $(wildcard **/*.c))
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
all: $(HEX)
$(HEX): $(BIN) $(FSDIR)
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
cp boot2.bin $(FSDIR)
cmp $(HEX) $(FPGA_IMG); \
RETVAL=$$?; \
if [ $$RETVAL -eq 0 ]; then \
echo "SAME"; \
else \
echo "NOT SAME"; \
cp bios.hex ../../hw/efinix_fpga/init_hex.mem; \
echo "Update ROM or rebuild FPGA image!"; \
fi
$(FSDIR):
mkdir $(FSDIR)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
%.o: %.c $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
%.o: %.s $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
$(LISTS):
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
.PHONY: clean
clean:
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map

View File

@@ -1,54 +0,0 @@
; ---------------------------------------------------------------------------
; crt0.s
; ---------------------------------------------------------------------------
;
; Startup code for cc65 (Single Board Computer version)
.export _init, _exit
.import _main
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import __SDRAM_START__, __SDRAM_SIZE__ ; Linker generated
.import copydata, zerobss, initlib, donelib
.include "zeropage.inc"
; ---------------------------------------------------------------------------
; Place the startup code in a special segment
.segment "STARTUP"
; ---------------------------------------------------------------------------
; A little light 6502 housekeeping
_init: LDX #$FF ; Initialize stack pointer to $01FF
TXS
CLD ; Clear decimal mode
; ---------------------------------------------------------------------------
; Set cc65 argument stack pointer
LDA #<(__SDRAM_START__ + __SDRAM_SIZE__)
STA sp
LDA #>(__SDRAM_START__ + __SDRAM_SIZE__)
STA sp+1
; ---------------------------------------------------------------------------
; Initialize memory storage
JSR zerobss ; Clear BSS segment
JSR copydata ; Initialize DATA segment
JSR initlib ; Run constructors
; ---------------------------------------------------------------------------
; Call main()
cli
JSR _main
jmp ($fffc)
; ---------------------------------------------------------------------------
; Back from main (this is also the _exit entry): force a software break
_exit: JSR donelib ; Run destructors
BRK

View File

@@ -1,352 +0,0 @@
.importzp sp, ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, sreg, data_start
.autoimport on
.export fatbuf
.feature string_escapes
.MACPACK generic
fatbuf = $A000
filebuf = $B000
.bss
tbase: .res 2
tlen: .res 2
dbase: .res 2
dlen: .res 2
olen: .res 1
otype: .res 1
filesiz: .res 1
cluster: .res 2
.zeropage
userptr: .res 2
.segment "BOOTLOADER"
sectors_per_cluster = $800D
reserved_sectors = $800E
fat_count = $8010
sectors_per_fat = $8024
O65_NO_C65 = $00
O65_MAGIC = $02
O65_VERSION = $05
O65_MODE = $06
O65_TBASE = $08
O65_TLEN = $0a
O65_DBASE = $0c
O65_DLEN = $0e
O65_BBASE = $10
O65_BLEN = $12
O65_ZBASE = $14
O65_ZLEN = $16
O65_STACK = $18
O65_OPT_START = $1A
_start:
lda #<str
ldx #>str
jsr _cputs
; Read root directory entry into fatbuf
lda data_start
ldx data_start + 1
jsr pushax
stz sreg
stz sreg+1
jsr pusheax
lda #<fatbuf
ldx #>fatbuf
jsr pushax
lda #<ptr1
ldx #>ptr1
jsr _SD_readSingleBlock
; lda #<fatbuf
; ldx #>fatbuf
; jsr _SD_printBuf
lda #$20 ; Start at first directory entry (first is a disk label)
sta ptr3
lda #>fatbuf
sta ptr3 + 1
ldy #$0b ; look for attributes
@1: lda (ptr3),y
cmp #$0f ; if attribute is 0xf, this is a lfn
bne @2 ; if not an lfn, then try to read filename
@next: clc ; otherwise, go to the next entry (+0x20)
lda ptr3
adc #$20
sta ptr3
bcc @4
inc ptr3 + 1
@4: lda #<word_str
ldx #>word_str
jsr pushax
lda ptr3
ldx ptr3 + 1
pha
phx
jsr pushax
phy
ldy #$4
jsr _cprintf
ply
plx
stx ptr3 + 1
pla
sta ptr3
bra @1
@2: ldy #11 ; ignore the attributes. Write null to make a string
lda #$00
sta (ptr3),y
lda ptr3 ; store address of the filename string on the stack
pha
ldx ptr3 + 1
phx
jsr _cputs ; print out short filenames as we read them
lda #$0d
jsr _cputc
lda #$0a
jsr _cputc
lda #<kernel_str ; load the string "KERNEL O65"
ldx #>kernel_str
jsr pushax
plx ; then push the string we read earlier
pla
jsr _strcmp
bne @next ; if they are not equal then try next entry
lda #<_good ; print match if we found it
ldx #>_good
jsr _cputs ; otherwise continue on
lda #<word_str
ldx #>word_str
jsr pushax
lda ptr3
pha
lda ptr3 + 1
pha
ldy #$1d ; load file size (256)
lda (ptr3),y
lsr ; divide by 2 to get file size (512)
sta filesiz
jsr pusha0
ldy #$4
jsr _cprintf
pla
sta ptr3 + 1
pla
sta ptr3
ldy #$1b ; load high byte of low first cluster
lda (ptr3),y
tax
dey
lda (ptr3),y ; load low byte of low first cluster
sec
sbc #$02 ; don't handle carry, assume low byte is not 0 or 1
clc
sta tmp1
ldx data_start + 1 ; load x as high data start
phx
ldx sectors_per_cluster ; multiply cluster num (minus 2) by sectors_per_cluster
lda #$00
@8: adc tmp1
dex
bne @8
plx
clc
adc data_start ; add that to low data start
bcc @5 ; handle carry
inx
@5: sta cluster
stx cluster + 1
lda #<filebuf
ldx #>filebuf
sta userptr
stx userptr + 1
@read_sd:
lda cluster
ldx cluster + 1
stz sreg
stz sreg+1
jsr pusheax
lda userptr
ldx userptr + 1
jsr pushax
lda #<ptr1
ldx #>ptr1
jsr _SD_readSingleBlock
; lda userptr
; ldx userptr + 1
; jsr _SD_printBuf
dec filesiz
bmi @doneload
inc cluster
inc userptr + 1
inc userptr + 1
bra @read_sd
@doneload:
ldy #O65_TBASE
lda filebuf,y
sta tbase
iny
ldx filebuf,y
stx tbase + 1
ldy #O65_TLEN
lda filebuf,y
sta tlen
iny
ldx filebuf,y
stx tlen + 1
ldy #O65_DBASE
lda filebuf,y
sta dbase
iny
ldx filebuf,y
stx dbase + 1
ldy #O65_DLEN
lda filebuf,y
sta dlen
iny
ldx filebuf,y
stx dlen + 1
ldy #O65_OPT_START
phy
@opt_len:
lda #<opt_str
ldx #>opt_str
jsr pushax
ply
lda filebuf,y
beq @opt_end
sta olen
phy
jsr pusha0
ply
iny
lda filebuf,y
sta otype
phy
jsr pusha0
ldy #$6
jsr _cprintf
lda #<word_str
ldx #>word_str
jsr pushax
pla
clc
adc olen
dec
pha
bra @opt_len
@opt_end:
iny ; account for reading size
phy
lda #<opt_done
ldx #>opt_done
jsr pushax
pla
pha
jsr pusha0
ldy #$4
jsr _cprintf
clc
pla
ldx #>filebuf
adc #<filebuf
bcc @6
inx
@6: sta userptr
stx userptr + 1
lda #<word_str
ldx #>word_str
jsr pushax
lda userptr
ldx userptr + 1
jsr pushax
ldy #$4
jsr _cprintf
lda tbase
ldx tbase + 1
jsr pushax
lda userptr
ldx userptr + 1
jsr pushax
lda tlen
ldx tlen + 1
jsr _memcpy
; lda #<$1000
; ldx #>$1000
; jsr _SD_printBuf
clc
lda userptr + 1
adc tlen + 1
tax
lda userptr
adc tlen
bcc @7
inx
@7: sta userptr
stx userptr + 1
lda #<word_str
ldx #>word_str
jsr pushax
lda userptr
ldx userptr + 1
jsr pushax
ldy #$4
jsr _cprintf
lda dbase
ldx dbase + 1
jsr pushax
lda userptr
ldx userptr + 1
jsr pushax
lda dlen
ldx dlen + 1
jsr _memcpy
jmp $1000
@end: bra @end
str: .asciiz "boot2\n"
kernel_str: .asciiz "KERNEL O65"
_good: .asciiz "Found KERNEL\n"
word_str: .asciiz "Word Value: %x\n"
opt_str: .asciiz "Opt Len: %x, Opt Type: %x\n"
opt_done: .asciiz "Options done. total option length: %x\n"

View File

@@ -1,201 +0,0 @@
.importzp sp, ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, sreg
.exportzp data_start
.autoimport on
.feature string_escapes
.MACPACK generic
.MACPACK longbranch
_console_clear = $0
_console_read_char = $2
_console_write_char = $4
_sd_readblock = $6
sectors_per_cluster = $800D
reserved_sectors = $800E
fat_count = $8010
sectors_per_fat = $8024
buf = $8200
addrh = $0000
addrl = $0000
.zeropage
data_start: .res 2
.segment "BOOTSECTOR"
_start:
jmp _main
.byte "SUPR6502"
_preamble:
.res (11+_start-_preamble)
_bpb: .res 60
_main:
lda #<str
ldx #>str
jsr _cputs
lda fat_count
cmp #$2
jne @fail
lda sectors_per_fat
asl
pha
lda sectors_per_fat + 1
rol
tax
pla
adc reserved_sectors
bcc @a
inx
@a: sta data_start
stx data_start + 1
jsr pushax
stz sreg
stz sreg+1
jsr pusheax
lda #<buf
ldx #>buf
jsr pushax
lda #<ptr1
ldx #>ptr1
jsr _SD_readSingleBlock
; lda #<buf
; ldx #>buf
; jsr _SD_printBuf
lda #$20 ; Start at first directory entry (first is a disk label)
sta ptr3
lda #>buf
sta ptr3 + 1
ldy #$0b ; look for attributes
@1: lda (ptr3),y
cmp #$0f ; if attribute is 0xf, this is a lfn
bne @2 ; if not an lfn, then try to read filename
clc ; otherwise, go to the next entry (+0x20)
lda ptr3
adc #$20
sta ptr3
bra @1
@2: ldy #11 ; ignore the attributes. Write null to make a string
lda #$00
sta (ptr3),y
lda ptr3 ; store address of the filename string on the stack
pha
ldx ptr3 + 1
phx
lda #<_boot2_str ; load the string "BOOT2 BIN"
ldx #>_boot2_str
jsr pushax
plx ; then push the string we read earlier
pla
jsr _strcmp
bne @fail ; if they are not equal then fail
lda #<_good ; TODO: We should try the next entry
ldx #>_good
jsr _cputs ; otherwise continue on
ldy #$1b ; load the high byte of the low first cluster
lda (ptr3),y
tax
dey
lda (ptr3),y ; load the low byte of the low first cluster
sec
sbc #$02 ; don't handle carry, assume low byte is not 0 or 1
clc
sta tmp1
ldx data_start + 1 ; load x as high data start
phx
ldx sectors_per_cluster ; multiply cluster num (minus 2) by sectors_per_cluster
lda #$00
@4: adc tmp1
dex
bne @4
plx
clc
adc data_start ; add that to low data start
bcc @3 ; handle carry
inx
@3: stz sreg
stz sreg+1
phx
pha
jsr pusheax
lda #<buf
ldx #>buf
jsr pushax
lda #<ptr1
ldx #>ptr1
jsr _SD_readSingleBlock
stz sreg
stz sreg+1
pla
plx
inc
jsr pusheax
lda #<buf
ldx #>buf
inx
inx
jsr pushax
lda #<ptr1
ldx #>ptr1
jsr _SD_readSingleBlock
jmp buf
bra @end
; Now we have the cluster number of the bootloader (3)
; this means we need to read from address 00ef_e000 + ((3 -2) * 8 * 512)
; 00eff000 is the address we want, which is efe000 + 4096
@fail: lda #<_fail
ldx #>_fail
jsr _cputs
@end: bra @end
str: .asciiz "boot\n"
_boot2_str: .asciiz "BOOT2 BIN"
_fail: .asciiz "not bootloader\n"
_good: .asciiz "found bootloader!\n"
_cluster: .asciiz "cluster: %lx\n"
_addr: .asciiz "addr: %x\n"
_end:
.res (440+_start-_end)
.res 6
.res 16
.res 16
.res 16
.res 16
.byte $55
.byte $AA

View File

@@ -1,10 +0,0 @@
#ifndef _BOARD_IO_H
#define _BOARD_IO_H
#include <stdint.h>
uint8_t sw_read();
void led_set(uint8_t val);
#endif

View File

@@ -1,24 +0,0 @@
.include "io.inc65"
.importzp sp, sreg
.export _sw_read
.export _led_set
.autoimport on
.code
; @out A: The Value of the switches
; Reads the current values of the switches.
_sw_read:
lda SW
ldx #$0
rts
; @in A: val
; @out A: 0 for success, 1 for failure
; Sets the LEDs
_led_set:
sta LED
rts

View File

@@ -1,60 +0,0 @@
.importzp sp, sreg
.import _uart_txb_block
.import _lastchar
.export _cputc
.export gotoxy
.export _clrscr
;.export _cgetc
.autoimport on
.code
; void __fastcall__ cputc (char c);
_cputc:
jsr _uart_txb_block
cmp #$0a
bne @1
lda #$0d
jsr _uart_txb_block
@1: rts
; void __fastcall__ gotoxy (unsigned char x, unsigned char y);
gotoxy:
phx
phy
tay ; Move y position to y
lda (sp)
tax ; Move x position to x
lda #$1b
jsr _uart_txb_block
lda #'['
jsr _uart_txb_block
tya
jsr _uart_txb_block
lda #';'
jsr _uart_txb_block
txa
jsr _uart_txb_block
lda #'H'
jsr _uart_txb_block
ply
plx
rts
_clrscr:
phx
lda #$1b
jsr _uart_txb_block
lda #'c'
jsr _uart_txb_block
pla
rts
;_cgetc:
;@2: lda _lastchar
; beq @2
; stz _lastchar
; rts

View File

@@ -1,15 +0,0 @@
#ifndef _INTERRUPT_H
#define _INTERRUPT_H
#include <stdint.h>
#define BUTTON (1 << 0)
#define UART (1 << 1)
void irq_int();
void nmi_int();
uint8_t irq_get_status();
void irq_set_status(uint8_t);
#endif

View File

@@ -1,27 +0,0 @@
; ---------------------------------------------------------------------------
; interrupt.s
; ---------------------------------------------------------------------------
;
; Interrupt handler.
;
; Checks for a BRK instruction and returns from all valid interrupts.
.export _irq_int, _nmi_int
IRQ_VECTOR = $220
NMI_VECTOR = $222
.segment "CODE"
.PC02 ; Force 65C02 assembly mode
; ---------------------------------------------------------------------------
; Non-maskable interrupt (NMI) service routine
_nmi_int: jmp (NMI_VECTOR)
; ---------------------------------------------------------------------------
; Maskable interrupt (IRQ) service routine
_irq_int: jmp (IRQ_VECTOR)

View File

@@ -1,13 +0,0 @@
UART = $efe6
UART_TXB = UART
UART_RXB = UART
UART_STATUS = UART + 1
LED = $efff
SW = LED
SPI_BAUD = $efd8
SPI_INPUT = $efd9
SPI_OUTPUT = $efda
SPI_CTRL = $efdb
SPI_STATUS = SPI_CTRL

View File

@@ -1,445 +0,0 @@
#include <conio.h>
#include "sd_card.h"
#include "sd_print.h"
#include "spi.h"
/*******************************************************************************
Initialize SD card
*******************************************************************************/
uint8_t SD_init()
{
uint16_t i;
uint8_t res[5], cmdAttempts = 0;
SD_powerUpSeq();
while((res[0] = SD_goIdleState()) != SD_IN_IDLE_STATE)
{
cmdAttempts++;
if(cmdAttempts == CMD0_MAX_ATTEMPTS)
{
cputs("Go IDLE\n");
return SD_ERROR;
}
}
#ifndef RTL_SIM
for (i = 0; i < 1000; i++);
#endif
SD_sendIfCond(res);
if(res[0] != SD_IN_IDLE_STATE)
{
cputs("IF Cond\n");
return SD_ERROR;
}
if(res[4] != 0xAA)
{
return SD_ERROR;
}
cmdAttempts = 0;
do
{
if(cmdAttempts == CMD55_MAX_ATTEMPTS)
{
cputs("op_cond error\n");
return SD_ERROR;
}
res[0] = SD_sendApp();
if(SD_R1_NO_ERROR(res[0]))
{
res[0] = SD_sendOpCond();
}
#ifndef RTL_SIM
for (i = 0; i < 1000; i++);
#endif
cmdAttempts++;
}
while(res[0] != SD_READY);
#ifndef RTL_SIM
for (i = 0; i < 1000; i++);
#endif
SD_readOCR(res);
return SD_SUCCESS;
}
/*
// Send a command with starting end ending clock pulses
uint8_t res1_cmd(uint8_t cmd, uint32_t arg, uint8_t crc)
{
uint8_t res1;
// assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
// send CMD0
SD_command(cmd, arg, crc);
// read response
res1 = SD_readRes1();
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
return res1;
}
*/
/*******************************************************************************
Run power up sequence
*******************************************************************************/
/*
void SD_powerUpSeq()
{
uint16_t i;
uint8_t j;
// make sure card is deselected
spi_deselect(0);
// give SD card time to power up
for (i = 0; i < 1000; i++);
// select SD card
spi_exchange(0xFF);
spi_deselect(0);
// send 80 clock cycles to synchronize
for(j = 0; j < SD_INIT_CYCLES; j++)
spi_exchange(0xFF);
}
*/
/*******************************************************************************
Send command to SD card
*******************************************************************************/
/*
void SD_command(uint8_t cmd, uint32_t arg, uint8_t crc)
{
// transmit command to sd card
spi_exchange(cmd|0x40);
// transmit argument
spi_exchange((uint8_t)(arg >> 24));
spi_exchange((uint8_t)(arg >> 16));
spi_exchange((uint8_t)(arg >> 8));
spi_exchange((uint8_t)(arg));
// transmit crc
spi_exchange(crc|0x01);
}
*/
/*******************************************************************************
Read R1 from SD card
*******************************************************************************/
/*
uint8_t SD_readRes1()
{
uint8_t i = 0, res1;
// keep polling until actual data received
while((res1 = spi_exchange(0xFF)) == 0xFF)
{
i++;
// if no data received for 8 bytes, break
if(i > 8) break;
}
return res1;
}
*/
/*******************************************************************************
Read R2 from SD card
*******************************************************************************/
/*
void SD_readRes2(uint8_t *res)
{
// read response 1 in R2
res[0] = SD_readRes1();
// read final byte of response
res[1] = spi_exchange(0xFF);
}
*/
/*******************************************************************************
Read R3 from SD card
*******************************************************************************/
/*
void SD_readRes3(uint8_t *res)
{
// read response 1 in R3
res[0] = SD_readRes1();
// if error reading R1, return
if(res[0] > 1) return;
// read remaining bytes
SD_readBytes(res + 1, R3_BYTES);
}
*/
/*******************************************************************************
Read R7 from SD card
*******************************************************************************/
/*
void SD_readRes7(uint8_t *res)
{
// read response 1 in R7
res[0] = SD_readRes1();
// if error reading R1, return
if(res[0] > 1) return;
// read remaining bytes
SD_readBytes(res + 1, R7_BYTES);
}
*/
/*******************************************************************************
Read specified number of bytes from SD card
*******************************************************************************/
/*
void SD_readBytes(uint8_t *res, uint8_t n)
{
while(n--) *res++ = spi_exchange(0xFF);
}
*/
/*******************************************************************************
Command Idle State (CMD0)
*******************************************************************************/
uint8_t SD_goIdleState()
{
return res1_cmd(CMD0, CMD0_ARG, CMD0_CRC);
}
/*******************************************************************************
Send Interface Conditions (CMD8)
*******************************************************************************/
void SD_sendIfCond(uint8_t *res)
{
// assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
// send CMD8
SD_command(CMD8, CMD8_ARG, CMD8_CRC);
// read response
SD_readRes7(res);
//SD_readBytes(res + 1, R7_BYTES);
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
}
/*******************************************************************************
Read Status
*******************************************************************************/
void SD_sendStatus(uint8_t *res)
{
// assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
// send CMD13
SD_command(CMD13, CMD13_ARG, CMD13_CRC);
// read response
SD_readRes2(res);
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
}
/*******************************************************************************
Read single 512 byte block
token = 0xFE - Successful read
token = 0x0X - Data error
token = 0xFF - timeout
*******************************************************************************/
// uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
// {
// uint8_t res1, read;
// uint16_t readAttempts;
// uint16_t i;
// // set token to none
// *token = 0xFF;
// // assert chip select
// spi_exchange(0xFF);
// spi_select(0);
// spi_exchange(0xFF);
// // send CMD17
// SD_command(CMD17, addr, CMD17_CRC);
// // read R1
// res1 = SD_readRes1();
// // if response received from card
// if(res1 != 0xFF)
// {
// // wait for a response token (timeout = 100ms)
// readAttempts = 0;
// while(++readAttempts != SD_MAX_READ_ATTEMPTS)
// if((read = spi_exchange(0xFF)) != 0xFF) break;
// cprintf("read attempts: %d\n", readAttempts);
// // if response token is 0xFE
// if(read == SD_START_TOKEN)
// {
// // read 512 byte block
// for(i = 0; i < SD_BLOCK_LEN; i++) *buf++ = spi_exchange(0xFF);
// // read 16-bit CRC
// spi_exchange(0xFF);
// spi_exchange(0xFF);
// }
// // set token to card response
// *token = read;
// }
// // deassert chip select
// spi_exchange(0xFF);
// spi_deselect(0);
// spi_exchange(0xFF);
// return res1;
// }
#define SD_MAX_WRITE_ATTEMPTS 3907
/*******************************************************************************
Write single 512 byte block
token = 0x00 - busy timeout
token = 0x05 - data accepted
token = 0xFF - response timeout
*******************************************************************************/
uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
{
uint16_t readAttempts;
uint8_t res1, read;
uint16_t i;
/*
// set token to none
*token = 0xFF;
// assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
// send CMD24
SD_command(CMD24, addr, CMD24_CRC);
// read response
res1 = SD_readRes1();
// if no error
if(res1 == SD_READY)
{
// send start token
spi_exchange(SD_START_TOKEN);
// write buffer to card
for(i = 0; i < SD_BLOCK_LEN; i++) spi_exchange(buf[i]);
// wait for a response (timeout = 250ms)
readAttempts = 0;
while(++readAttempts != SD_MAX_WRITE_ATTEMPTS)
if((read = spi_exchange(0xFF)) != 0xFF) { *token = 0xFF; break; }
// if data accepted
if((read & 0x1F) == 0x05)
{
// set token to data accepted
*token = 0x05;
// wait for write to finish (timeout = 250ms)
readAttempts = 0;
while(spi_exchange(0xFF) == 0x00)
if(++readAttempts == SD_MAX_WRITE_ATTEMPTS) { *token = 0x00; break; }
}
}
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
*/
return res1;
}
/*******************************************************************************
Reads OCR from SD Card
*******************************************************************************/
void SD_readOCR(uint8_t *res)
{
uint8_t tmp;
// assert chip select
spi_exchange(0xFF);
spi_select(0);
tmp = spi_exchange(0xFF);
if(tmp != 0xFF) while(spi_exchange(0xFF) != 0xFF) ;
// send CMD58
SD_command(CMD58, CMD58_ARG, CMD58_CRC);
// read response
SD_readRes3(res);
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
}
/*******************************************************************************
Send application command (CMD55)
*******************************************************************************/
uint8_t SD_sendApp()
{
return res1_cmd(CMD55, CMD55_ARG, CMD55_CRC);;
}
/*******************************************************************************
Send operating condition (ACMD41)
*******************************************************************************/
uint8_t SD_sendOpCond()
{
return res1_cmd(ACMD41, ACMD41_ARG, ACMD41_CRC);
}

View File

@@ -1,80 +0,0 @@
#ifndef _SD_CARD_H
#define _SD_CARD_H
#include <stdint.h>
// command definitions
#define CMD0 0
#define CMD0_ARG 0x00000000
#define CMD0_CRC 0x94
#define CMD8 8
#define CMD8_ARG 0x0000001AA
#define CMD8_CRC 0x86
#define CMD9 9
#define CMD9_ARG 0x00000000
#define CMD9_CRC 0x00
#define CMD10 9
#define CMD10_ARG 0x00000000
#define CMD10_CRC 0x00
#define CMD13 13
#define CMD13_ARG 0x00000000
#define CMD13_CRC 0x00
#define CMD17 17
#define CMD17_CRC 0x00
#define CMD24 24
#define CMD24_CRC 0x00
#define CMD55 55
#define CMD55_ARG 0x00000000
#define CMD55_CRC 0x00
#define CMD58 58
#define CMD58_ARG 0x00000000
#define CMD58_CRC 0x00
#define ACMD41 41
#define ACMD41_ARG 0x40000000
#define ACMD41_CRC 0x00
#define SD_IN_IDLE_STATE 0x01
#define SD_READY 0x00
#define SD_R1_NO_ERROR(X) X < 0x02
#define R3_BYTES 4
#define R7_BYTES 4
#define CMD0_MAX_ATTEMPTS 255
#define CMD55_MAX_ATTEMPTS 255
#define SD_ERROR 1
#define SD_SUCCESS 0
#define SD_MAX_READ_ATTEMPTS 1563
#define SD_READ_START_TOKEN 0xFE
#define SD_INIT_CYCLES 80
#define SD_START_TOKEN 0xFE
#define SD_ERROR_TOKEN 0x00
#define SD_DATA_ACCEPTED 0x05
#define SD_DATA_REJECTED_CRC 0x0B
#define SD_DATA_REJECTED_WRITE 0x0D
#define SD_BLOCK_LEN 512
// SD functions
uint8_t SD_init();
void SD_powerUpSeq();
void SD_command(uint8_t cmd, uint32_t arg, uint8_t crc);
uint8_t SD_readRes1();
void SD_readRes2(uint8_t *res);
void SD_readRes3(uint8_t *res);
void SD_readRes7(uint8_t *res);
void SD_readBytes(uint8_t *res, uint8_t n);
uint8_t SD_goIdleState();
void SD_sendIfCond(uint8_t *res);
void SD_sendStatus(uint8_t *res);
void SD_readOCR(uint8_t *res);
uint8_t SD_sendApp();
uint8_t SD_sendOpCond();
uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *error);
uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *res);
uint8_t res1_cmd(uint8_t cmd, uint32_t arg, uint8_t crc);
#endif

View File

@@ -1,303 +0,0 @@
.export _SD_command
.export _SD_readRes1
.export _SD_readRes2
.export _SD_readRes3
.export _SD_readRes7
.export _SD_readBytes
.export _SD_powerUpSeq
.export _res1_cmd
.export _SD_readSingleBlock
.importzp sp, ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3
.autoimport on
.MACPACK generic
; void SD_command(uint8_t cmd, uint32_t arg, uint8_t crc)
; The plan: push crc to stack, load arg into tmp1 through 4
.proc _SD_command: near
pha ; Push CRC to cpu stack
ldy #$04
lda (sp),y ; Load CMD
ora #$40 ; start bit
jsr _spi_exchange
dey
arg_loop: ; send ARG
lda (sp),y ; is this sending only 3?
jsr _spi_exchange
dey
bpl arg_loop
pla ; Pull CRC from stack
ora #$01 ; stop bit
jsr _spi_exchange
jsr incsp5 ; pop all off stack
rts
.endproc
; uint8_t SD_readRes1 (void)
.proc _SD_readRes1: near
; Try to read/write up to 8 times, then return value
ldx #$08
tryread:
lda #$ff
jsr _spi_exchange
cmp #$ff
bne end
dex
bne tryread
end: ; x will be 0 here anyway
rts
.endproc
; void SD_readRes2(uint8_t *res)
.proc _SD_readRes2: near
sta ptr1 ; store res in ptr1
stx ptr1 + 1
jsr _SD_readRes1 ; get first response 1
sta (ptr1)
lda #$ff
jsr _spi_exchange ; get final byte of response
ldy #$01
sta (ptr1),y
jsr incsp2
rts
.endproc
; void SD_readBytes(uint8_t *res, uint8_t n)
.proc _SD_readBytes: near
tax
jsr popptr1 ; store res in ptr1
read:
lda #$ff ; read data first
jsr _spi_exchange
sta (ptr1)
inc ptr1 ; then increment res
bne @L1
inc ptr1 + 1
@L1: dex ; then decrement x
bne read ; and if x is zero we are done
rts
.endproc
; void SD_readRes7(uint8_t *res)
_SD_readRes7:
; void SD_readRes3(uint8_t *res)
.proc _SD_readRes3: near
sta ptr1 ; store res in ptr1
stx ptr1 + 1
jsr _SD_readRes1 ; read respopnse 1 in R3
cmp #$02 ; if error reading R1, return
bge @L1
inc ptr1 ; read remaining bytes
bne @L2
inc ptr1
@L2: lda ptr1 ; push low byte
ldx ptr1 + 1
jsr pushax
lda #$04 ; R3_BYTES
jsr _SD_readBytes
@L1: rts
.endproc
; uint8_t res1_cmd(uint8_t cmd, uint32_t arg, uint8_t crc)
.proc _res1_cmd: near
pha ; push crc to processor stack
lda #$ff
jsr _spi_exchange
lda #$00 ; this gets ignored anyway
jsr _spi_select
lda #$ff
jsr _spi_exchange
pla
jsr _SD_command ; rely on command to teardown stack
jsr _SD_readRes1
tay ; spi doesn't touch y
lda #$ff
jsr _spi_exchange
lda #$00 ; this gets ignored anyway
jsr _spi_deselect
lda #$ff
jsr _spi_exchange
tya
ldx #$00 ; Promote to integer
rts
.endproc
; void SD_powerUpSeq(void)
.proc _SD_powerUpSeq: near
lda #$00
jsr _spi_deselect
jsr _sd_delay
lda #$ff
jsr _spi_exchange
lda #$00
jsr _spi_deselect
ldx #$50 ; SD_INIT_CYCLES
@L1: lda #$ff
jsr _spi_exchange
dex
bne @L1
rts
.endproc
; 1ms delay approx. saves no registers
.proc _sd_delay: near
ldx #$01 ; delay loop: A*X*10 + 4
@L1: lda #$c8 ; 1ms at 2MHz
@L2: dec ; 2
bne @L2 ; 3
dex ; 2
bne @L1 ; 3
rts
.endproc
; ;uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
.proc _SD_readSingleBlock: near
; token address in a/x
; buf address next on stack
; sd address above that
; ptr2 = *token
sta ptr2
stx ptr2 + 1
lda #$ff
sta (ptr2)
; ptr1 = *buf
jsr popptr1
; 4 bytes on stack are addr
; Move addr down on the stack
lda sp
sta ptr3
lda sp + 1
sta ptr3 + 1
; find a way to do this in a loop?
jsr decsp1
ldy #$0
lda (ptr3),y
sta (sp),y
iny
lda (ptr3),y
sta (sp),y
iny
lda (ptr3),y
sta (sp),y
iny
lda (ptr3),y
sta (sp),y
lda #$ff
jsr _spi_exchange
lda #$00 ; this gets ignored anyway
jsr _spi_select
lda #$ff
jsr _spi_exchange
; push cmd17
lda #$11
ldy #$4
sta (sp),y
; crc, 0
lda #$00
jsr _SD_command ; rely on command to teardown stack
jsr _SD_readRes1
cmp #$ff ; if 0xFF then you failed
beq end
sta tmp3 ; tmp3 = read
; y = read_attempts
ldy #$0
resp_loop:
lda #$ff
jsr _spi_exchange
sta tmp2 ; tmp2 = read
lda tmp2
cmp #$ff
bne got_resp
iny
bne resp_loop
bra after_read
got_resp:
ldx #$2
ldy #$00
load_loop:
lda #$ff
jsr _spi_exchange
sta (ptr1)
inc ptr1
bne @2
inc ptr1 + 1
@2: dey
bne load_loop
ldy #$00
dex
bne load_loop
lda #$ff
jsr _spi_exchange
lda #$ff
jsr _spi_exchange
after_read:
lda tmp2
sta (ptr2)
lda tmp3
end:
pha
lda #$ff
jsr _spi_exchange
lda #$00 ; this gets ignored anyway
jsr _spi_deselect
lda #$ff
jsr _spi_exchange
pla
rts
.endproc

View File

@@ -1,26 +0,0 @@
#include <conio.h>
#include "sd_print.h"
#include "sd_card.h"
void SD_printBuf(uint8_t *buf)
{
uint8_t colCount = 0;
uint16_t i;
for(i = 0; i < SD_BLOCK_LEN; i++)
{
cprintf("%2x", *buf++);
if(colCount == 31)
{
cputs("\n");
colCount = 0;
}
else
{
cputc(' ');
colCount++;
}
}
cputs("\n");
}

View File

@@ -1,61 +0,0 @@
#ifndef SD_PRINT_H
#define SD_PRINT_H
#include <stdint.h>
/* R1 MACROS */
#define PARAM_ERROR(X) X & 0b01000000
#define ADDR_ERROR(X) X & 0b00100000
#define ERASE_SEQ_ERROR(X) X & 0b00010000
#define CRC_ERROR(X) X & 0b00001000
#define ILLEGAL_CMD(X) X & 0b00000100
#define ERASE_RESET(X) X & 0b00000010
#define IN_IDLE(X) X & 0b00000001
/* R2 MACROS */
#define OUT_OF_RANGE(X) X & 0b10000000
#define ERASE_PARAM(X) X & 0b01000000
#define WP_VIOLATION(X) X & 0b00100000
#define CARD_ECC_FAILED(X) X & 0b00010000
#define CC_ERROR(X) X & 0b00001000
#define ERROR(X) X & 0b00000100
#define WP_ERASE_SKIP(X) X & 0b00000010
#define CARD_LOCKED(X) X & 0b00000001
/* R3 MACROS */
#define POWER_UP_STATUS(X) X & 0x40
#define CCS_VAL(X) X & 0x40
#define VDD_2728(X) X & 0b10000000
#define VDD_2829(X) X & 0b00000001
#define VDD_2930(X) X & 0b00000010
#define VDD_3031(X) X & 0b00000100
#define VDD_3132(X) X & 0b00001000
#define VDD_3233(X) X & 0b00010000
#define VDD_3334(X) X & 0b00100000
#define VDD_3435(X) X & 0b01000000
#define VDD_3536(X) X & 0b10000000
/* R7 MACROS */
#define CMD_VER(X) ((X >> 4) & 0xF0)
#define VOL_ACC(X) (X & 0x1F)
#define VOLTAGE_ACC_27_33 0b00000001
#define VOLTAGE_ACC_LOW 0b00000010
#define VOLTAGE_ACC_RES1 0b00000100
#define VOLTAGE_ACC_RES2 0b00001000
/* DATA ERROR TOKEN */
#define SD_TOKEN_OOR(X) X & 0b00001000
#define SD_TOKEN_CECC(X) X & 0b00000100
#define SD_TOKEN_CC(X) X & 0b00000010
#define SD_TOKEN_ERROR(X) X & 0b00000001
void SD_printR1(uint8_t res);
void SD_printR2(uint8_t *res);
void SD_printR3(uint8_t *res);
void SD_printR7(uint8_t *res);
void SD_printBuf(uint8_t *buf);
void SD_printDataErrToken(uint8_t token);
#endif

View File

@@ -1,12 +0,0 @@
#ifndef _SPI_H
#define _SPI_H
#include <stdint.h>
void spi_select(uint8_t id);
void spi_deselect(uint8_t id);
uint8_t spi_read();
void spi_write(uint8_t data);
uint8_t spi_exchange(uint8_t data);
#endif

View File

@@ -1,39 +0,0 @@
.include "io.inc65"
.importzp zp, sreg
.export _spi_select, _spi_deselect
.export _spi_read, _spi_write, _spi_exchange
.autoimport on
.code
; void spi_select(uint8_t id)
; Select a (the) slave by pulling its CS line down
; TODO allow active high or active low CS
; TODO allow more than one slave
_spi_select:
lda #$1 ; Ignore whatever id is, 1 is the only option
sta SPI_CTRL
rts
; void spi_deslect(uint8_t id)
; Deslect a slave by pulling its CS line up
; TODO allow active high or active low CS
_spi_deselect:
stz SPI_CTRL
rts
; uint8_t spi_read()
_spi_read:
lda #$0
; void spi_write(uint8_t data)
_spi_write:
; uint8_t spi_exchange(uint8_t data)
_spi_exchange:
sta SPI_OUTPUT
@1: lda SPI_CTRL
bmi @1
lda SPI_INPUT
rts

View File

@@ -1,13 +0,0 @@
#ifndef _UART_H
#define _UART_H
#include <stdint.h>
void uart_txb(uint8_t val);
void uart_txb_block(uint8_t val);
uint8_t uart_rxb();
uint8_t uart_status();
#endif

View File

@@ -1,36 +0,0 @@
.include "io.inc65"
.importzp sp, sreg
.export _uart_txb, _uart_txb_block
.export _uart_rxb
.export _uart_status
.autoimport on
.code
; @in A: byte to transmit
; Transmits a byte over the UART
_uart_txb:
sta UART_TXB ; Just write value, don't wait
rts
_uart_txb_block:
pha
sta UART_TXB ; Write value
@1: lda UART_STATUS ; Wait for status[1] to be 0
bit #$02
bne @1
pla
rts
_uart_rxb:
lda UART_RXB ; Read value
ldx #$00
rts
_uart_status:
lda UART_STATUS
ldx #$00
rts

View File

@@ -1,40 +0,0 @@
MEMORY
{
ZP: start = $0, size = $100, type = rw, define = yes;
KERNEL: start = $1000, size = $7000, type = rw, define = yes;
SDRAM: start = $9200, size = $4d00, type = rw, define = yes;
BOOTSECTOR: start = $8000, size = $200, type = rw, define = yes, file = "bootloader.bin";
BOOTLOADER: start = $8200, size = $1000, type = rw, define = yes, file = "boot2.bin";
ROM: start = $F000, size = $1000, file = %O;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
DATA: load = ROM, type = rw, define = yes, run = SDRAM;
BSS: load = SDRAM, type = bss, define = yes;
HEAP: load = SDRAM, type = bss, optional = yes;
STARTUP: load = ROM, type = ro;
ONCE: load = ROM, type = ro, optional = yes;
CODE: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
VECTORS: load = ROM, type = ro, start = $FFFA;
BOOTSECTOR: load = BOOTSECTOR, type = rw, start = $8000;
BOOTLOADER: load = BOOTLOADER, type = rw;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
# Define the stack size for the application
__STACKSIZE__: value = $0200, type = weak;
__STACKSTART__: type = weak, value = $0800; # 2k stack
}

View File

@@ -1,55 +0,0 @@
#include <stdint.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include "devices/board_io.h"
#include "devices/uart.h"
#include "devices/sd_card.h"
#include "devices/sd_print.h"
#define KERNEL_LOAD_ADDR 0xD000
//uint8_t buf[512];
uint8_t *buf = (uint8_t*)0x8000;
int main() {
// array to hold responses
uint8_t res[5], token;
uint32_t addr = 0x00000000;
uint16_t i;
cputs("Start\n");
// initialize sd card
if(SD_init() != SD_SUCCESS)
{
cputs("Error\n");
}
else
{
cputs("Success\n");
res[0] = SD_readSingleBlock(addr, buf, &token);
// if no error, print buffer
if((res[0] == 0x00) && (token == SD_START_TOKEN)) {
#ifndef RTL_SIM
SD_printBuf(buf);
#endif
}
//else if error token received, print
else if(!(token & 0xF0))
{
cputs("Error\n");
} else {
cprintf("bad token: %x\n", token);
}
__asm__ ("jmp (%v)", buf);
}
while(1) ;
}

View File

@@ -1,14 +0,0 @@
; ---------------------------------------------------------------------------
; vectors.s
; ---------------------------------------------------------------------------
;
; Defines the interrupt vector table.
.import _init
.import _nmi_int, _irq_int
.segment "VECTORS"
.addr _nmi_int ; NMI vector
.addr _init ; Reset vector
.addr _irq_int ; IRQ/BRK vector

Submodule sw/cc65 deleted from 9824f6e3d4

View File

@@ -1 +0,0 @@
This is a text file, which is composed of text.

View File

@@ -1,33 +0,0 @@
very large text file with a very long name
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?~!@#$%^&*()_+`1234567890-=[]\{}|;':",./<>?

View File

@@ -1,40 +0,0 @@
CC=../cc65/bin/cl65
LD=../cc65/bin/cl65
CFLAGS=-T -t none -I. --cpu "65C02"
LDFLAGS=-C link.ld -m $(NAME).map
NAME=kernel
O65 = $(NAME).o65
FSDIR=$(REPO_TOP)/sw/fsdir
LISTS=lists
SRCS=$(wildcard *.s) $(wildcard *.c)
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
# Make sure the kernel linked to correct address, no relocation!
all: $(O65) $(FSDIR)
cp $(O65) $(FSDIR)
$(FSDIR):
mkdir $(FSDIR)
$(O65): $(OBJS)
$(LD) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
%.o: %.c $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
%.o: %.s $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
$(LISTS):
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
.PHONY: clean
clean:
rm -rf $(OBJS) $(O65) $(LISTS) $(NAME).map

View File

@@ -1,53 +0,0 @@
; ---------------------------------------------------------------------------
; crt0.s
; ---------------------------------------------------------------------------
;
; Startup code for cc65 (Single Board Computer version)
.export _init, _exit
.import _main, _cputc
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import __STACKSTART__, __STACKSIZE__ ; Linker generated
.import copydata, zerobss, initlib, donelib
.include "zeropage.inc"
; ---------------------------------------------------------------------------
; Place the startup code in a special segment
.segment "STARTUP"
; ---------------------------------------------------------------------------
; A little light 6502 housekeeping
_init: LDX #$FF ; Initialize stack pointer to $01FF
TXS
CLD ; Clear decimal mode
; ---------------------------------------------------------------------------
; Set cc65 argument stack pointer
LDA #<(__STACKSTART__ + __STACKSIZE__)
STA sp
LDA #>(__STACKSTART__ + __STACKSIZE__)
STA sp+1
; ---------------------------------------------------------------------------
; Initialize memory storage
JSR zerobss ; Clear BSS segment (no longer fails)
; JSR copydata ; Initialize DATA segment (this also fails. but prints something)
JSR initlib ; Run constructors (This one works)
; ---------------------------------------------------------------------------
; Call main()
cli
JSR _main
; ---------------------------------------------------------------------------
; Back from main (this is also the _exit entry): force a software break
_exit: JSR donelib ; Run destructors
BRK

View File

@@ -1,10 +0,0 @@
#ifndef _BOARD_IO_H
#define _BOARD_IO_H
#include <stdint.h>
uint8_t sw_read();
void led_set(uint8_t val);
#endif

View File

@@ -1,24 +0,0 @@
.include "io.inc65"
.importzp sp, sreg
.export _sw_read
.export _led_set
.autoimport on
.code
; @out A: The Value of the switches
; Reads the current values of the switches.
_sw_read:
lda SW
ldx #$0
rts
; @in A: val
; @out A: 0 for success, 1 for failure
; Sets the LEDs
_led_set:
sta LED
rts

View File

@@ -1,60 +0,0 @@
.importzp sp, sreg
.import _uart_txb_block
.import _lastchar
.export _cputc
.export gotoxy
.export _clrscr
;.export _cgetc
.autoimport on
.code
; void __fastcall__ cputc (char c);
_cputc:
jsr _uart_txb_block
cmp #$0a
bne @1
lda #$0d
jsr _uart_txb_block
@1: rts
; void __fastcall__ gotoxy (unsigned char x, unsigned char y);
gotoxy:
phx
phy
tay ; Move y position to y
lda (sp)
tax ; Move x position to x
lda #$1b
jsr _uart_txb_block
lda #'['
jsr _uart_txb_block
tya
jsr _uart_txb_block
lda #';'
jsr _uart_txb_block
txa
jsr _uart_txb_block
lda #'H'
jsr _uart_txb_block
ply
plx
rts
_clrscr:
phx
lda #$1b
jsr _uart_txb_block
lda #'c'
jsr _uart_txb_block
pla
rts
;_cgetc:
;@2: lda _lastchar
; beq @2
; stz _lastchar
; rts

View File

@@ -1,32 +0,0 @@
#ifndef _INTERRUPT_CONTROLLER_H
#define _INTERRUPT_CONTROLLER_H
#include <stdint.h>
// These need to be copied in interrupt_controller.s
#define IRQ_CMD_ADDR 0xeffc
#define IRQ_DAT_ADDR 0xeffd
#define IRQ_CMD_MASK 0xe0
#define IRQ_REG_MASK 0x1f
#define IRQ_CMD_READIRQ 0x00
#define IRQ_CMD_ENABLE 0x20
#define IRQ_CMD_TYPE 0x40
#define IRQ_CMD_EOI 0xff
#define IRQ_EDGE 0
#define IRQ_LEVEL 1
void init_interrupt_controller();
void enable_irq(uint8_t type, uint8_t irqnum);
void disable_irq(uint8_t irqnum);
// This should accept irqnum later.
void send_eoi();
#endif

View File

@@ -1,148 +0,0 @@
.MACPACK generic
.autoimport
.importzp tmp1, tmp2
.export _init_interrupt_controller
.export _enable_irq
.export _disable_irq
.export _send_eoi
.import irq_int, nmi_int
IRQ_CMD_ADDR = $effc
IRQ_DAT_ADDR = $effd
IRQ_CMD_MASK = $e0
IRQ_REG_MASK = $1f
IRQ_CMD_READIRQ = $00
IRQ_CMD_ENABLE = $20
IRQ_CMD_TYPE = $40
IRQ_CMD_EOI = $ff
IRQ_VECTOR = $220
NMI_VECTOR = $222
.code
; void init_irq();
; mask all IRQs, set all type to edge.
.proc _init_interrupt_controller
lda #<irq_int
sta IRQ_VECTOR
lda #>irq_int
sta IRQ_VECTOR+1
lda #<nmi_int
sta NMI_VECTOR
lda #>nmi_int
sta NMI_VECTOR+1
ldx #$20 ; enable
ldy #00
jsr cmd_all
ldx #$40 ; edge type
ldy #$00
jsr cmd_all
rts
cmd_all: ; Send the same value to all 32 bytes
txa
add #$10
sta tmp1
loop:
txa
sta IRQ_CMD_ADDR
tya
sta IRQ_DAT_ADDR
inx
cpx tmp1
blt loop
rts
.endproc
; void enable_irq(uint8_t type, uint8_t irqnum);
; in A:
.proc _enable_irq
; Decide which byte we need to modify by dividing by 8 (>> 3)
pha
lsr
lsr
lsr ; A is now bytesel
sta tmp2 ; tmp2 is now bytesel
add #IRQ_CMD_ENABLE
sta IRQ_CMD_ADDR
lda IRQ_DAT_ADDR
sta tmp1
pla
and #$07 ; A is now 0-7
tax
inx ; X is now 1-8
lda #$01
L1: dex
beq L2
asl
bra L1
L2: pha ; Push bit mask to stack
ora tmp1 ; A is now 1 << (0-7) | enable
sta IRQ_DAT_ADDR
lda tmp2
add #IRQ_CMD_TYPE
sta IRQ_CMD_ADDR
lda IRQ_DAT_ADDR
sta tmp1
jsr popa ; A is now type
beq bit0
bit1: ; set `bit` to 1
pla
ora tmp1
bra L3
bit0: ; set `bit` to 0
pla
eor #$ff
and tmp1
L3: sta IRQ_DAT_ADDR
rts
.endproc
; TODO this is mostly the same as enable, why copy?
.proc _disable_irq
; Decide which byte we need to modify by dividing by 32 (>> 5)
pha
lsr
lsr
lsr ; A is now bytesel
add #IRQ_CMD_ENABLE
sta IRQ_CMD_ADDR
lda IRQ_DAT_ADDR
sta tmp1
pla
and $07 ; A is now 0-7
tax
inx ; X is now 1-8
lda #$01
L1: dex
beq L2
asl
bra L1
L2: eor #$ff ; Invert to set enable to 0
and tmp1 ; a is now ~(1 << (0-7)) & enable
sta IRQ_DAT_ADDR
rts
.endproc
; This should accept irqnum later.
; void send_eoi();
.proc _send_eoi
lda #IRQ_CMD_EOI
sta IRQ_CMD_ADDR
lda #$1
sta IRQ_DAT_ADDR
rts
.endproc

View File

@@ -1,30 +0,0 @@
UART = $efe6
UART_TXB = UART
UART_RXB = UART
UART_STATUS = UART + 1
LED = $efff
SW = LED
SPI_BAUD = $efd8
SPI_INPUT = $efd9
SPI_OUTPUT = $efda
SPI_CTRL = $efdb
SPI_STATUS = SPI_CTRL
MULTIPLIER_BASE = $eff0
MULTIPLIER_AL = MULTIPLIER_BASE + 0
MULTIPLIER_AH = MULTIPLIER_BASE + 1
MULTIPLIER_BL = MULTIPLIER_BASE + 2
MULTIPLIER_BH = MULTIPLIER_BASE + 3
MULTIPLIER_OLL = MULTIPLIER_BASE + 4
MULTIPLIER_OLH = MULTIPLIER_BASE + 5
MULTIPLIER_OHL = MULTIPLIER_BASE + 6
MULTIPLIER_OHH = MULTIPLIER_BASE + 7
GOLDEN_OUTPUT_0 = $03
GOLDEN_OUTPUT_1 = $0a
GOLDEN_OUTPUT_2 = $08
GOLDEN_OUTPUT_3 = $00

View File

@@ -1,10 +0,0 @@
#ifndef _MAPPER_H
#define _MAPPER_H
#include <stdint.h>
void init_mapper();
void map(uint16_t p_page, uint8_t v_page);
#endif

View File

@@ -1,38 +0,0 @@
.MACPACK generic
.autoimport
.export _init_mapper
.export _map
MAPPER_BASE = $200
.code
; void init_paging();
; This should be identity mapped at reset, but we can do it again anyway
.proc _init_mapper
ldx #$00
L1:
txa
lsr
sta MAPPER_BASE,x
lda #$00
sta MAPPER_BASE+1,x
inx
inx
cpx #$20
blt L1
rts
.endproc
; void map(uint16_t p_page, uint8_t v_page);
.proc _map
asl
tax ; x = v_page * 2
jsr popa ; low byte of p_page
sta MAPPER_BASE,x ; write low byte to mm_low
jsr popa ; high byte of p_page
sta MAPPER_BASE+1,x ; write high byte to mm_high
rts
.endproc

View File

@@ -1,12 +0,0 @@
#ifndef _MULTIPLER_H
#define _MULTIPLER_H
#include <stdint.h>
/* Multiply 2 integers into 1 long */
uint32_t lmulii(uint16_t a, uint16_t b);
/* Multiply 2 integers into 1 integer, discarding upper bits. */
uint16_t imulii(uint16_t a, uint16_t b);
#endif

View File

@@ -1,36 +0,0 @@
.include "io.inc65"
.MACPACK generic
.import popax
.importzp sreg
.export _lmulii, _imulii
.code
.proc _lmulii
sta MULTIPLIER_BL
stx MULTIPLIER_BH
jsr popax
sta MULTIPLIER_AL
stx MULTIPLIER_AH
lda MULTIPLIER_OHL
sta sreg
lda MULTIPLIER_OHH
sta sreg+1
lda MULTIPLIER_OLL
ldx MULTIPLIER_OLH
rts
.endproc
.proc _imulii
sta MULTIPLIER_BL
stx MULTIPLIER_BH
jsr popax
sta MULTIPLIER_AL
stx MULTIPLIER_AH
lda MULTIPLIER_OLL
ldx MULTIPLIER_OLH
rts
.endproc

View File

@@ -1,25 +0,0 @@
#ifndef _RTC_H
#define _RTC_H
#include <stdint.h>
#define RTC_CMD_ADDR 0xeffe
#define RTC_DAT_ADDR 0xefff
#define RTC_THRESHOLD 0x00
#define RTC_INCREMENT 0x10
#define RTC_IRQ_THRESHOLD 0x20
#define RTC_OUTPUT 0x30
#define RTC_CONTROL 0x30
/* initialize RTC with default values */
void init_rtc(void);
/* handle RTC interrupts */
void handle_rtc(void);
void rtc_set(uint32_t val, uint8_t idx);
#endif

View File

@@ -1,112 +0,0 @@
.MACPACK generic
.importzp tmp1
.import popa
.export _init_rtc
.export _handle_rtc
.export _rtc_set
RTC_CMD = $effe
RTC_DAT = $efff
RTC_THRESHOLD = $00
RTC_INCREMENT = $10
RTC_IRQ_THRESHOLD = $20
RTC_OUTPUT = $30
RTC_CONTROL = $30
THRESHOLD_0 = $a0
THRESHOLD_1 = $0f
; THRESHOLD_1 = $00
THRESHOLD_2 = $00
THRESHOLD_3 = $00
IRQ_THRESHOLD_0 = $32
; IRQ_THRESHOLD_0 = $10
IRQ_THRESHOLD_1 = $00
IRQ_THRESHOLD_2 = $00
IRQ_THRESHOLD_3 = $00
; void init_rtc(void);
; Initialize rtc and generate 50ms interrupts
.proc _init_rtc
lda #RTC_INCREMENT+0 ; Set increment to 1
sta RTC_CMD
lda #$01
sta RTC_DAT
lda #RTC_INCREMENT+1
sta RTC_CMD
lda #$00
sta RTC_DAT
lda #RTC_INCREMENT+2
sta RTC_CMD
lda #$00
sta RTC_DAT
lda #RTC_INCREMENT+3
sta RTC_CMD
lda #$00
sta RTC_DAT
lda #RTC_THRESHOLD+0 ; Set threshold to 4000 ($fa0)
sta RTC_CMD
lda #THRESHOLD_0
sta RTC_DAT
lda #RTC_THRESHOLD+1
sta RTC_CMD
lda #THRESHOLD_1
sta RTC_DAT
lda #RTC_THRESHOLD+2
sta RTC_CMD
lda #THRESHOLD_2
sta RTC_DAT
lda #RTC_THRESHOLD+3
sta RTC_CMD
lda #THRESHOLD_3
sta RTC_DAT
lda #RTC_IRQ_THRESHOLD+0 ; Set irq threshold to 50 ($32)
sta RTC_CMD
lda #IRQ_THRESHOLD_0
sta RTC_DAT
lda #RTC_IRQ_THRESHOLD+1
sta RTC_CMD
lda #IRQ_THRESHOLD_1
sta RTC_DAT
lda #RTC_IRQ_THRESHOLD+2
sta RTC_CMD
lda #IRQ_THRESHOLD_2
sta RTC_DAT
lda #RTC_IRQ_THRESHOLD+3
sta RTC_CMD
lda #IRQ_THRESHOLD_3
sta RTC_DAT
lda #$30
sta RTC_CMD
lda #$3
sta RTC_DAT
rts
.endproc
; void rtc_set(uint32_t val, uint8_t idx);
.proc _rtc_set
sta tmp1 ; store idx in tmp1
ldx #$04
L1: lda tmp1
sta RTC_CMD ; store cmd+idx to CMD
jsr popa ; pop 1 byte of argument
sta RTC_DAT ; write it to data
inc tmp1 ; increase index
dex
bne L1 ; repeat 4 times
rts
.endproc
.proc _handle_rtc
nop
rti
.endproc

View File

@@ -1,445 +0,0 @@
#include <conio.h>
#include "sd_card.h"
#include "sd_print.h"
#include "spi.h"
/*******************************************************************************
Initialize SD card
*******************************************************************************/
uint8_t SD_init()
{
uint16_t i;
uint8_t res[5], cmdAttempts = 0;
SD_powerUpSeq();
while((res[0] = SD_goIdleState()) != SD_IN_IDLE_STATE)
{
cmdAttempts++;
if(cmdAttempts == CMD0_MAX_ATTEMPTS)
{
cputs("Go IDLE\r\n");
return SD_ERROR;
}
}
for (i = 0; i < 1000; i++);
SD_sendIfCond(res);
if(res[0] != SD_IN_IDLE_STATE)
{
cputs("IF Cond\r\n");
return SD_ERROR;
}
if(res[4] != 0xAA)
{
return SD_ERROR;
}
cmdAttempts = 0;
do
{
if(cmdAttempts == CMD55_MAX_ATTEMPTS)
{
cputs("op_cond error\r\n");
return SD_ERROR;
}
res[0] = SD_sendApp();
if(SD_R1_NO_ERROR(res[0]))
{
res[0] = SD_sendOpCond();
}
for (i = 0; i < 1000; i++);
cmdAttempts++;
}
while(res[0] != SD_READY);
for (i = 0; i < 1000; i++);
SD_readOCR(res);
return SD_SUCCESS;
}
/*
// Send a command with starting end ending clock pulses
uint8_t res1_cmd(uint8_t cmd, uint32_t arg, uint8_t crc)
{
uint8_t res1;
// assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
// send CMD0
SD_command(cmd, arg, crc);
// read response
res1 = SD_readRes1();
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
return res1;
}
*/
/*******************************************************************************
Run power up sequence
*******************************************************************************/
/*
void SD_powerUpSeq()
{
uint16_t i;
uint8_t j;
// make sure card is deselected
spi_deselect(0);
// give SD card time to power up
for (i = 0; i < 1000; i++);
// select SD card
spi_exchange(0xFF);
spi_deselect(0);
// send 80 clock cycles to synchronize
for(j = 0; j < SD_INIT_CYCLES; j++)
spi_exchange(0xFF);
}
*/
/*******************************************************************************
Send command to SD card
*******************************************************************************/
/*
void SD_command(uint8_t cmd, uint32_t arg, uint8_t crc)
{
// transmit command to sd card
spi_exchange(cmd|0x40);
// transmit argument
spi_exchange((uint8_t)(arg >> 24));
spi_exchange((uint8_t)(arg >> 16));
spi_exchange((uint8_t)(arg >> 8));
spi_exchange((uint8_t)(arg));
// transmit crc
spi_exchange(crc|0x01);
}
*/
/*******************************************************************************
Read R1 from SD card
*******************************************************************************/
/*
uint8_t SD_readRes1()
{
uint8_t i = 0, res1;
// keep polling until actual data received
while((res1 = spi_exchange(0xFF)) == 0xFF)
{
i++;
// if no data received for 8 bytes, break
if(i > 8) break;
}
return res1;
}
*/
/*******************************************************************************
Read R2 from SD card
*******************************************************************************/
/*
void SD_readRes2(uint8_t *res)
{
// read response 1 in R2
res[0] = SD_readRes1();
// read final byte of response
res[1] = spi_exchange(0xFF);
}
*/
/*******************************************************************************
Read R3 from SD card
*******************************************************************************/
/*
void SD_readRes3(uint8_t *res)
{
// read response 1 in R3
res[0] = SD_readRes1();
// if error reading R1, return
if(res[0] > 1) return;
// read remaining bytes
SD_readBytes(res + 1, R3_BYTES);
}
*/
/*******************************************************************************
Read R7 from SD card
*******************************************************************************/
/*
void SD_readRes7(uint8_t *res)
{
// read response 1 in R7
res[0] = SD_readRes1();
// if error reading R1, return
if(res[0] > 1) return;
// read remaining bytes
SD_readBytes(res + 1, R7_BYTES);
}
*/
/*******************************************************************************
Read specified number of bytes from SD card
*******************************************************************************/
/*
void SD_readBytes(uint8_t *res, uint8_t n)
{
while(n--) *res++ = spi_exchange(0xFF);
}
*/
/*******************************************************************************
Command Idle State (CMD0)
*******************************************************************************/
uint8_t SD_goIdleState()
{
return res1_cmd(CMD0, CMD0_ARG, CMD0_CRC);
}
/*******************************************************************************
Send Interface Conditions (CMD8)
*******************************************************************************/
void SD_sendIfCond(uint8_t *res)
{
// assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
// send CMD8
SD_command(CMD8, CMD8_ARG, CMD8_CRC);
// read response
SD_readRes7(res);
//SD_readBytes(res + 1, R7_BYTES);
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
}
/*******************************************************************************
Read Status
*******************************************************************************/
void SD_sendStatus(uint8_t *res)
{
// assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
// send CMD13
SD_command(CMD13, CMD13_ARG, CMD13_CRC);
// read response
SD_readRes2(res);
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
}
/*******************************************************************************
Read single 512 byte block
token = 0xFE - Successful read
token = 0x0X - Data error
token = 0xFF - timeout
*******************************************************************************/
// uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
// {
// uint8_t res1, read;
// uint16_t readAttempts;
// uint16_t i;
// // set token to none
// *token = 0xFF;
// // assert chip select
// spi_exchange(0xFF);
// spi_select(0);
// spi_exchange(0xFF);
// // send CMD17
// SD_command(CMD17, addr, CMD17_CRC);
// // read R1
// res1 = SD_readRes1();
// // if response received from card
// if(res1 != 0xFF)
// {
// // wait for a response token (timeout = 100ms)
// readAttempts = 0;
// while(++readAttempts != SD_MAX_READ_ATTEMPTS)
// if((read = spi_exchange(0xFF)) != 0xFF) break;
// cprintf("read attempts: %d\r\n", readAttempts);
// // if response token is 0xFE
// if(read == SD_START_TOKEN)
// {
// // read 512 byte block
// for(i = 0; i < SD_BLOCK_LEN; i++) *buf++ = spi_exchange(0xFF);
// // read 16-bit CRC
// spi_exchange(0xFF);
// spi_exchange(0xFF);
// }
// // set token to card response
// *token = read;
// }
// // deassert chip select
// spi_exchange(0xFF);
// spi_deselect(0);
// spi_exchange(0xFF);
// return res1;
// }
#define SD_MAX_WRITE_ATTEMPTS 3907
/*******************************************************************************
Write single 512 byte block
token = 0x00 - busy timeout
token = 0x05 - data accepted
token = 0xFF - response timeout
*******************************************************************************/
uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
{
(void)addr;
(void)buf;
(void)token;
/*
uint16_t readAttempts;
uint8_t res1, read;
uint16_t i;
// set token to none
*token = 0xFF;
// assert chip select
spi_exchange(0xFF);
spi_select(0);
spi_exchange(0xFF);
// send CMD24
SD_command(CMD24, addr, CMD24_CRC);
// read response
res1 = SD_readRes1();
// if no error
if(res1 == SD_READY)
{
// send start token
spi_exchange(SD_START_TOKEN);
// write buffer to card
for(i = 0; i < SD_BLOCK_LEN; i++) spi_exchange(buf[i]);
// wait for a response (timeout = 250ms)
readAttempts = 0;
while(++readAttempts != SD_MAX_WRITE_ATTEMPTS)
if((read = spi_exchange(0xFF)) != 0xFF) { *token = 0xFF; break; }
// if data accepted
if((read & 0x1F) == 0x05)
{
// set token to data accepted
*token = 0x05;
// wait for write to finish (timeout = 250ms)
readAttempts = 0;
while(spi_exchange(0xFF) == 0x00)
if(++readAttempts == SD_MAX_WRITE_ATTEMPTS) { *token = 0x00; break; }
}
}
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
return res1;
*/
return 0;
}
/*******************************************************************************
Reads OCR from SD Card
*******************************************************************************/
void SD_readOCR(uint8_t *res)
{
uint8_t tmp;
// assert chip select
spi_exchange(0xFF);
spi_select(0);
tmp = spi_exchange(0xFF);
if(tmp != 0xFF) while(spi_exchange(0xFF) != 0xFF) ;
// send CMD58
SD_command(CMD58, CMD58_ARG, CMD58_CRC);
// read response
SD_readRes3(res);
// deassert chip select
spi_exchange(0xFF);
spi_deselect(0);
spi_exchange(0xFF);
}
/*******************************************************************************
Send application command (CMD55)
*******************************************************************************/
uint8_t SD_sendApp()
{
return res1_cmd(CMD55, CMD55_ARG, CMD55_CRC);;
}
/*******************************************************************************
Send operating condition (ACMD41)
*******************************************************************************/
uint8_t SD_sendOpCond()
{
return res1_cmd(ACMD41, ACMD41_ARG, ACMD41_CRC);
}

View File

@@ -1,80 +0,0 @@
#ifndef _SD_CARD_H
#define _SD_CARD_H
#include <stdint.h>
// command definitions
#define CMD0 0
#define CMD0_ARG 0x00000000
#define CMD0_CRC 0x94
#define CMD8 8
#define CMD8_ARG 0x0000001AA
#define CMD8_CRC 0x86
#define CMD9 9
#define CMD9_ARG 0x00000000
#define CMD9_CRC 0x00
#define CMD10 9
#define CMD10_ARG 0x00000000
#define CMD10_CRC 0x00
#define CMD13 13
#define CMD13_ARG 0x00000000
#define CMD13_CRC 0x00
#define CMD17 17
#define CMD17_CRC 0x00
#define CMD24 24
#define CMD24_CRC 0x00
#define CMD55 55
#define CMD55_ARG 0x00000000
#define CMD55_CRC 0x00
#define CMD58 58
#define CMD58_ARG 0x00000000
#define CMD58_CRC 0x00
#define ACMD41 41
#define ACMD41_ARG 0x40000000
#define ACMD41_CRC 0x00
#define SD_IN_IDLE_STATE 0x01
#define SD_READY 0x00
#define SD_R1_NO_ERROR(X) X < 0x02
#define R3_BYTES 4
#define R7_BYTES 4
#define CMD0_MAX_ATTEMPTS 255
#define CMD55_MAX_ATTEMPTS 255
#define SD_ERROR 1
#define SD_SUCCESS 0
#define SD_MAX_READ_ATTEMPTS 1563
#define SD_READ_START_TOKEN 0xFE
#define SD_INIT_CYCLES 80
#define SD_START_TOKEN 0xFE
#define SD_ERROR_TOKEN 0x00
#define SD_DATA_ACCEPTED 0x05
#define SD_DATA_REJECTED_CRC 0x0B
#define SD_DATA_REJECTED_WRITE 0x0D
#define SD_BLOCK_LEN 512
// SD functions
uint8_t SD_init();
void SD_powerUpSeq();
void SD_command(uint8_t cmd, uint32_t arg, uint8_t crc);
uint8_t SD_readRes1();
void SD_readRes2(uint8_t *res);
void SD_readRes3(uint8_t *res);
void SD_readRes7(uint8_t *res);
void SD_readBytes(uint8_t *res, uint8_t n);
uint8_t SD_goIdleState();
void SD_sendIfCond(uint8_t *res);
void SD_sendStatus(uint8_t *res);
void SD_readOCR(uint8_t *res);
uint8_t SD_sendApp();
uint8_t SD_sendOpCond();
uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *error);
uint8_t SD_writeSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *res);
uint8_t res1_cmd(uint8_t cmd, uint32_t arg, uint8_t crc);
#endif

View File

@@ -1,303 +0,0 @@
.export _SD_command
.export _SD_readRes1
.export _SD_readRes2
.export _SD_readRes3
.export _SD_readRes7
.export _SD_readBytes
.export _SD_powerUpSeq
.export _res1_cmd
.export _SD_readSingleBlock
.importzp sp, ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3
.autoimport on
.MACPACK generic
; void SD_command(uint8_t cmd, uint32_t arg, uint8_t crc)
; The plan: push crc to stack, load arg into tmp1 through 4
.proc _SD_command: near
pha ; Push CRC to cpu stack
ldy #$04
lda (sp),y ; Load CMD
ora #$40 ; start bit
jsr _spi_exchange
dey
arg_loop: ; send ARG
lda (sp),y ; is this sending only 3?
jsr _spi_exchange
dey
bpl arg_loop
pla ; Pull CRC from stack
ora #$01 ; stop bit
jsr _spi_exchange
jsr incsp5 ; pop all off stack
rts
.endproc
; uint8_t SD_readRes1 (void)
.proc _SD_readRes1: near
; Try to read/write up to 8 times, then return value
ldx #$08
tryread:
lda #$ff
jsr _spi_exchange
cmp #$ff
bne end
dex
bne tryread
end: ; x will be 0 here anyway
rts
.endproc
; void SD_readRes2(uint8_t *res)
.proc _SD_readRes2: near
sta ptr1 ; store res in ptr1
stx ptr1 + 1
jsr _SD_readRes1 ; get first response 1
sta (ptr1)
lda #$ff
jsr _spi_exchange ; get final byte of response
ldy #$01
sta (ptr1),y
jsr incsp2
rts
.endproc
; void SD_readBytes(uint8_t *res, uint8_t n)
.proc _SD_readBytes: near
tax
jsr popptr1 ; store res in ptr1
read:
lda #$ff ; read data first
jsr _spi_exchange
sta (ptr1)
inc ptr1 ; then increment res
bne @L1
inc ptr1 + 1
@L1: dex ; then decrement x
bne read ; and if x is zero we are done
rts
.endproc
; void SD_readRes7(uint8_t *res)
_SD_readRes7:
; void SD_readRes3(uint8_t *res)
.proc _SD_readRes3: near
sta ptr1 ; store res in ptr1
stx ptr1 + 1
jsr _SD_readRes1 ; read respopnse 1 in R3
cmp #$02 ; if error reading R1, return
bge @L1
inc ptr1 ; read remaining bytes
bne @L2
inc ptr1
@L2: lda ptr1 ; push low byte
ldx ptr1 + 1
jsr pushax
lda #$04 ; R3_BYTES
jsr _SD_readBytes
@L1: rts
.endproc
; uint8_t res1_cmd(uint8_t cmd, uint32_t arg, uint8_t crc)
.proc _res1_cmd: near
pha ; push crc to processor stack
lda #$ff
jsr _spi_exchange
lda #$00 ; this gets ignored anyway
jsr _spi_select
lda #$ff
jsr _spi_exchange
pla
jsr _SD_command ; rely on command to teardown stack
jsr _SD_readRes1
tay ; spi doesn't touch y
lda #$ff
jsr _spi_exchange
lda #$00 ; this gets ignored anyway
jsr _spi_deselect
lda #$ff
jsr _spi_exchange
tya
ldx #$00 ; Promote to integer
rts
.endproc
; void SD_powerUpSeq(void)
.proc _SD_powerUpSeq: near
lda #$00
jsr _spi_deselect
jsr _sd_delay
lda #$ff
jsr _spi_exchange
lda #$00
jsr _spi_deselect
ldx #$50 ; SD_INIT_CYCLES
@L1: lda #$ff
jsr _spi_exchange
dex
bne @L1
rts
.endproc
; 1ms delay approx. saves no registers
.proc _sd_delay: near
ldx #$01 ; delay loop: A*X*10 + 4
@L1: lda #$c8 ; 1ms at 2MHz
@L2: dec ; 2
bne @L2 ; 3
dex ; 2
bne @L1 ; 3
rts
.endproc
; ;uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *token)
.proc _SD_readSingleBlock: near
; token address in a/x
; buf address next on stack
; sd address above that
; ptr2 = *token
sta ptr2
stx ptr2 + 1
lda #$ff
sta (ptr2)
; ptr1 = *buf
jsr popptr1
; 4 bytes on stack are addr
; Move addr down on the stack
lda sp
sta ptr3
lda sp + 1
sta ptr3 + 1
; find a way to do this in a loop?
jsr decsp1
ldy #$0
lda (ptr3),y
sta (sp),y
iny
lda (ptr3),y
sta (sp),y
iny
lda (ptr3),y
sta (sp),y
iny
lda (ptr3),y
sta (sp),y
lda #$ff
jsr _spi_exchange
lda #$00 ; this gets ignored anyway
jsr _spi_select
lda #$ff
jsr _spi_exchange
; push cmd17
lda #$11
ldy #$4
sta (sp),y
; crc, 0
lda #$00
jsr _SD_command ; rely on command to teardown stack
jsr _SD_readRes1
cmp #$ff ; if 0xFF then you failed
beq end
sta tmp3 ; tmp3 = read
; y = read_attempts
ldy #$0
resp_loop:
lda #$ff
jsr _spi_exchange
sta tmp2 ; tmp2 = read
lda tmp2
cmp #$ff
bne got_resp
iny
bne resp_loop
bra after_read
got_resp:
ldx #$2
ldy #$00
load_loop:
lda #$ff
jsr _spi_exchange
sta (ptr1)
inc ptr1
bne @2
inc ptr1 + 1
@2: dey
bne load_loop
ldy #$00
dex
bne load_loop
lda #$ff
jsr _spi_exchange
lda #$ff
jsr _spi_exchange
after_read:
lda tmp2
sta (ptr2)
lda tmp3
end:
pha
lda #$ff
jsr _spi_exchange
lda #$00 ; this gets ignored anyway
jsr _spi_deselect
lda #$ff
jsr _spi_exchange
pla
rts
.endproc

View File

@@ -1,26 +0,0 @@
#include <conio.h>
#include "sd_print.h"
#include "sd_card.h"
void SD_printBuf(uint8_t *buf)
{
uint8_t colCount = 0;
uint16_t i;
for(i = 0; i < SD_BLOCK_LEN; i++)
{
cprintf("%2x", *buf++);
if(colCount == 31)
{
cputs("\r\n");
colCount = 0;
}
else
{
cputc(' ');
colCount++;
}
}
cputs("\r\n");
}

View File

@@ -1,61 +0,0 @@
#ifndef SD_PRINT_H
#define SD_PRINT_H
#include <stdint.h>
/* R1 MACROS */
#define PARAM_ERROR(X) X & 0b01000000
#define ADDR_ERROR(X) X & 0b00100000
#define ERASE_SEQ_ERROR(X) X & 0b00010000
#define CRC_ERROR(X) X & 0b00001000
#define ILLEGAL_CMD(X) X & 0b00000100
#define ERASE_RESET(X) X & 0b00000010
#define IN_IDLE(X) X & 0b00000001
/* R2 MACROS */
#define OUT_OF_RANGE(X) X & 0b10000000
#define ERASE_PARAM(X) X & 0b01000000
#define WP_VIOLATION(X) X & 0b00100000
#define CARD_ECC_FAILED(X) X & 0b00010000
#define CC_ERROR(X) X & 0b00001000
#define ERROR(X) X & 0b00000100
#define WP_ERASE_SKIP(X) X & 0b00000010
#define CARD_LOCKED(X) X & 0b00000001
/* R3 MACROS */
#define POWER_UP_STATUS(X) X & 0x40
#define CCS_VAL(X) X & 0x40
#define VDD_2728(X) X & 0b10000000
#define VDD_2829(X) X & 0b00000001
#define VDD_2930(X) X & 0b00000010
#define VDD_3031(X) X & 0b00000100
#define VDD_3132(X) X & 0b00001000
#define VDD_3233(X) X & 0b00010000
#define VDD_3334(X) X & 0b00100000
#define VDD_3435(X) X & 0b01000000
#define VDD_3536(X) X & 0b10000000
/* R7 MACROS */
#define CMD_VER(X) ((X >> 4) & 0xF0)
#define VOL_ACC(X) (X & 0x1F)
#define VOLTAGE_ACC_27_33 0b00000001
#define VOLTAGE_ACC_LOW 0b00000010
#define VOLTAGE_ACC_RES1 0b00000100
#define VOLTAGE_ACC_RES2 0b00001000
/* DATA ERROR TOKEN */
#define SD_TOKEN_OOR(X) X & 0b00001000
#define SD_TOKEN_CECC(X) X & 0b00000100
#define SD_TOKEN_CC(X) X & 0b00000010
#define SD_TOKEN_ERROR(X) X & 0b00000001
void SD_printR1(uint8_t res);
void SD_printR2(uint8_t *res);
void SD_printR3(uint8_t *res);
void SD_printR7(uint8_t *res);
void SD_printBuf(uint8_t *buf);
void SD_printDataErrToken(uint8_t token);
#endif

View File

@@ -1,17 +0,0 @@
#ifndef _SERIAL_H
#define _SERIAL_H
#include <stdint.h>
void serial_handle_irq();
void serial_init();
void serial_putc(char c);
void serial_puts(char* s);
char serial_getc();
char serial_getc_nb();
#endif

View File

@@ -1,94 +0,0 @@
.MACPACK generic
.autoimport
.import _enable_irq, _send_eoi, _uart_txb_block
.importzp tmp1, ptr1
.export _serial_init
.export _serial_handle_irq
.export _serial_putc, _serial_puts, _serial_getc, _serial_getc_nb
.zeropage
last_char: .res 1
.code
UART = $efe6
UART_TXB = UART
UART_RXB = UART
UART_STATUS = UART + 1
; Initialize Serial Port
; No initialization needed, just register irq handler.
.proc _serial_init
lda #<_serial_handle_irq
ldx #>_serial_handle_irq
jsr pushax
lda #$01
jsr _register_irq
stz last_char
rts
.endproc
; Serial Port IRQ Handler
; Get the character and store it.
.proc _serial_handle_irq
lda UART_RXB
ora #$80 ; set msb
sta last_char
jsr _send_eoi
rti
.endproc
; Serial Port Get Character
; If a character has not been received, block until one is.
.proc _serial_getc
L1: lda last_char
bpl L1
and #$7f
sta last_char
rts
.endproc
; Serial Port Get Character Non-Blocking
; return last character, even if it has already been read.
; If the character is new, we still clear the new flag.
.proc _serial_getc_nb
lda last_char
bpl L1
and #$7f
sta last_char
L1: rts
.endproc
; Serial Port Put Character
; send a single character over the serial port.
.proc _serial_putc
jsr _uart_txb_block
cmp #$0a
bne @1
lda #$0d
jsr _uart_txb_block
@1: rts
.endproc
; Send a string over the serial port. Needs stlen
.proc _serial_puts
sta ptr1 ; Store pointer in ptr1
stx ptr1+1
ldy #$00 ; initialize y to 0
L1: lda (ptr1),y ; load character from string
beq L2 ; Quit if NULL
jsr _serial_putc ; send character (does not change y or ptr1)
iny ; increment y
bne L1 ; If Y == 0, increment high byte of pointer
inc ptr1+1
bne L1 ; if high byte wraps around, give up
L2: rts
.endproc

View File

@@ -1,12 +0,0 @@
#ifndef _SPI_H
#define _SPI_H
#include <stdint.h>
void spi_select(uint8_t id);
void spi_deselect(uint8_t id);
uint8_t spi_read();
void spi_write(uint8_t data);
uint8_t spi_exchange(uint8_t data);
#endif

View File

@@ -1,39 +0,0 @@
.include "io.inc65"
.importzp zp, sreg
.export _spi_select, _spi_deselect
.export _spi_read, _spi_write, _spi_exchange
.autoimport on
.code
; void spi_select(uint8_t id)
; Select a (the) slave by pulling its CS line down
; TODO allow active high or active low CS
; TODO allow more than one slave
_spi_select:
lda #$1 ; Ignore whatever id is, 1 is the only option
sta SPI_CTRL
rts
; void spi_deslect(uint8_t id)
; Deslect a slave by pulling its CS line up
; TODO allow active high or active low CS
_spi_deselect:
stz SPI_CTRL
rts
; uint8_t spi_read()
_spi_read:
lda #$0
; void spi_write(uint8_t data)
_spi_write:
; uint8_t spi_exchange(uint8_t data)
_spi_exchange:
sta SPI_OUTPUT
@1: lda SPI_CTRL
bmi @1
lda SPI_INPUT
rts

View File

@@ -1,13 +0,0 @@
#ifndef _TERMINAL_H
#define _TERMINAL_H
#include <stdint.h>
int8_t terminal_read(uint8_t fd, void* buf, uint8_t nbytes);
int8_t terminal_write(uint8_t fd, const void* buf, uint8_t nbytes);
int8_t terminal_open(const uint8_t* filename);
int8_t terminal_close(uint8_t fd);
#endif /* _TERMINAL_H */

View File

@@ -1,145 +0,0 @@
.MACPACK generic
.autoimport
.importzp tmp1, ptr1
.import _serial_getc
.export _terminal_read, _terminal_write, _terminal_open, _terminal_close
.data
terminal_buf: .res 128
.code
; int8_t terminal_read(uint8_t fd, void* buf, uint8_t nbytes);
; Read up to size-1 (127 max) before the enter key is pressed.
; A newline character is automatically added.
; Inputs: int8_t* buf - where input characters are stored
; uint8_t n - number of characters to read (max buf size minux 1)
; Return Value: number of characters read on success, -1 on failure
; Function: Reads keyboard input
.proc _terminal_read
cmp #$00 ; Check that nbytes is > 0 and < 128
beq FAIL
cmp #$81
bge FAIL
sta tmp1 ; Store nbytes in tmp1
jsr popax ; Check that buf != NULL
cmp #$00
bne L1
cpx #$00
bne L1
bra FAIL
; while i < nbytes, store getc into terminal_buf y
L1: sta ptr1
stx ptr1+1
ldy #$00
LOOP: cpy tmp1
bge END
jsr _serial_getc
sta terminal_buf,y
cmp #$0d ; If newline, do something
bne L2
lda #$0a ; hacky serial, we want $0a, not $0d
jsr _serial_putc
bra END
L2: cmp #$08 ; Handle backspace
bne L3
lda tmp1
beq LOOP
lda #$08
jsr _serial_putc
dey
lda #$00
sta terminal_buf,y
bra LOOP
L3: lda terminal_buf,y ; Normal character
sta (ptr1),y
jsr _serial_putc
iny
bra LOOP
END: phy ; Zero out terminal buffer
ldy #$00
lda #$00
L4: sta terminal_buf,y
iny
cpy #$80
blt L4
L5: ply ; End string with NULL
lda #$0a
sta (ptr1),y
iny
cpy #$80 ; But not if we are at max
bge L6
lda #$00
sta (ptr1),y
L6: lda #$00 ; Return - on success
rts
FAIL: lda #$ff ; return -1 on fail
rts
.endproc
; int8_t terminal_write(uint8_t fd, const void* buf, uint8_t nbytes);
; write characters to the terminal
; Inputs: int8_t* buf - buffer of characters to write
; uint8_t n - number of characters to write
; Return Value: 0 on success, -1 on failure
; Writes to screen. Only stops after n chars written.
; This seems to not care about null termination?
.proc _terminal_write
sta tmp1 ; put nbytes in tmp1
jsr popax ; check that buf is not null
cmp #$00
bne L1
cpx #$00
bne L1
bra FAIL
L1: sta ptr1
stx ptr1+1
ldy #$00
LOOP: lda (ptr1),y ; Loop through buffer and print
jsr _serial_putc
iny
cpy tmp1
blt LOOP
lda #$00
rts
FAIL: lda #$ff ; old code didn't fail, but new code does.
rts
.endproc
; terminal_open
; open terminal device
; Inputs: uint8_t* filename
; Outputs: none
; Return Value: 0 on success
; Function: none.
.proc _terminal_open
lda #$0
rts
.endproc
; terminal_close
; close terminal device
; Inputs: int32_t fd
; Outputs: none
; Return Value: 0 on success (but this always failes)
; Function: none.
.proc _terminal_close
lda #$ff ; -1
rts
.endproc

View File

@@ -1,13 +0,0 @@
#ifndef _UART_H
#define _UART_H
#include <stdint.h>
void uart_txb(uint8_t val);
void uart_txb_block(uint8_t val);
uint8_t uart_rxb();
uint8_t uart_status();
#endif

View File

@@ -1,36 +0,0 @@
.include "io.inc65"
.importzp sp, sreg
.export _uart_txb, _uart_txb_block
.export _uart_rxb
.export _uart_status
.autoimport on
.code
; @in A: byte to transmit
; Transmits a byte over the UART
_uart_txb:
sta UART_TXB ; Just write value, don't wait
rts
_uart_txb_block:
pha
sta UART_TXB ; Write value
@1: lda UART_STATUS ; Wait for status[1] to be 0
bit #$02
bne @1
pla
rts
_uart_rxb:
lda UART_RXB ; Read value
ldx #$00
rts
_uart_status:
lda UART_STATUS
ldx #$00
rts

View File

@@ -1,53 +0,0 @@
#ifndef _FAT32_H
#define _FAT32_H
#include <stdint.h>
#include <stdio.h>
void fat32_init();
extern uint32_t root_cluster;
extern uint16_t fat_start_sector;
extern uint32_t data_start_sector;
extern uint32_t fat_size;
extern uint8_t* sd_buf;
extern uint8_t sectors_per_cluster;
extern uint8_t log2_sectors_per_cluster;
struct fat32_directory_entry {
char file_name[8];
char file_ext[3];
uint8_t attr1;
uint8_t attr2;
uint8_t create_time_10ms;
uint16_t create_time;
uint16_t create_date;
uint16_t access_date;
uint16_t cluster_high;
uint16_t modified_time;
uint16_t modified_date;
uint16_t cluster_low;
uint32_t file_size;
};
struct lfn_entry {
uint8_t sequence_number;
uint16_t name_0[5];
uint8_t attributes;
uint8_t type;
uint8_t checksum;
uint16_t name_1[6];
uint16_t cluster_low;
uint16_t name_2[2];
};
int8_t fat32_get_cluster_by_name(const char* name, struct fat32_directory_entry* dentry);
int8_t fat32_read_sector(uint32_t cluster, uint32_t sector, void* buf);
uint32_t fat32_next_cluster(uint32_t cluster);
int8_t fat32_file_open(const char* filename);
size_t fat32_file_read(int8_t fd, void* buf, size_t nbytes);
size_t fat32_file_write(int8_t fd, const void* buf, size_t nbytes);
int8_t fat32_file_close(int8_t fd);
#endif

View File

@@ -1,112 +0,0 @@
.MACPACK generic
.autoimport
.feature string_escapes
.importzp ptr1, sreg
.import _SD_readSingleBlock
.export _fat32_init
.export _root_cluster, _fat_start_sector, _data_start_sector
.export _fat_size, _sd_buf, _sectors_per_cluster, _log2_sectors_per_cluster
.data
_root_cluster: .res 4
_fat_start_sector: .res 2
_data_start_sector: .res 4
_fat_size: .res 4
_sectors_per_cluster: .res 1
_log2_sectors_per_cluster: .res 1
_sd_buf: .res 512
data_start_sect_str: .asciiz "Data sector start: 0x%lx\n"
starting_cluster_str: .asciiz "Root cluster num: %lx\n";
value_str: .asciiz "Value: 0x%x\n"
.code
bytes_per_sector = _sd_buf + $0B
sectors_per_cluster = _sd_buf + $0D
reserved_sectors = _sd_buf + $0E
fat_count = _sd_buf + $10
sectors_per_fat = _sd_buf + $24
root_cluster_offs = _sd_buf + $2C
.proc _fat32_init
; load sector 0 into sd_buf
lda #$00
ldx #$00
stz sreg
stz sreg+1
jsr pusheax
lda #<_sd_buf
ldx #>_sd_buf
jsr pushax
lda #<ptr1
ldx #>ptr1
jsr _SD_readSingleBlock
lda sectors_per_cluster
sta _sectors_per_cluster
ldx #$0
@1: bit #$01
bne L0
inx
lsr
bra @1
L0: txa
sta _log2_sectors_per_cluster
ldx #$00
L1: lda root_cluster_offs,x
sta _root_cluster,x
inx
cpx #$4
blt L1
; Multiply reserved sectors and bytes per sector, then divide by 512 to get sd sectors
lda reserved_sectors
jsr pusha0
lda bytes_per_sector
ldx bytes_per_sector+1
jsr _imulii
txa
lsr
sta _fat_start_sector
stz _fat_start_sector + 1
; multiply fat size and number of fats to get total fat size
lda fat_count
jsr pusha0
lda sectors_per_fat
ldx sectors_per_fat+1
jsr _lmulii
sta _fat_size
stx _fat_size+1
lda sreg
sta _fat_size+2
lda sreg+1
sta _fat_size+3
; Add fat size to starting fat sector to get data start sector
clc
lda _fat_size
adc _fat_start_sector
sta _data_start_sector
lda _fat_size+1
adc _fat_start_sector+1
sta _data_start_sector+1
lda _fat_size+2
sta _data_start_sector+2
lda _fat_size+3
sta _data_start_sector+3
rts
.endproc

View File

@@ -1,207 +0,0 @@
#include <devices/sd_card.h>
#include <process/process.h>
#include <conio.h>
#include <stdint.h>
#include <string.h>
#include "fat32.h"
#include "fs.h"
static struct fops fat32_file_ops = {fat32_file_open, fat32_file_close, fat32_file_read, fat32_file_write};
int8_t fd_val;
//TODO
size_t fat32_file_write(int8_t fd, const void* buf, size_t nbytes) {
(void)fd;
(void)buf;
(void)nbytes;
return -1;
}
/*
* file_close
* DESCRIPTION: close device abstracted as file
* INPUTS: fd -- file descriptor for file to be closed
* OUTPUTS: none
* RETURN VALUE: none
* SIDE EFFECTS: none
*/
int8_t fat32_file_close(int8_t fd) {
struct pcb* pcb;
pcb = get_pcb_ptr();
/* update pcb to remove process */
pcb->file_desc_array[fd].flags = !IN_USE;
return 0;
}
int8_t fat32_file_open(const char* filename) {
int8_t ret;
int8_t i;
int8_t fd;
struct fat32_directory_entry dentry;
struct pcb* pcb = get_pcb_ptr();
ret = fat32_get_cluster_by_name(filename, &dentry);
if (ret) {
cprintf("Error finding cluster for filename");
return -1;
}
/* try to find an empty file desciptor, fail otherwise */
//TODO We start at 3 here because 0, 1, 2 will be reserved later
for (i = 3; i < FILE_DESC_SIZE; i++) {
if (pcb->file_desc_array[i].flags == !IN_USE) {
fd = i;
break;
}
}
if (fd == -1){
return -1;
}
/* add process */
pcb->file_desc_array[fd].f32_dentry = dentry;
pcb->file_desc_array[fd].flags = IN_USE;
pcb->file_desc_array[fd].file_pos = 0;
pcb->file_desc_array[fd].file_ops = &fat32_file_ops;
return fd;
}
size_t fat32_file_read(int8_t fd, void* buf, size_t nbytes) {
uint16_t i;
size_t offset;
size_t leftover_length;
size_t bytes_read = 0;
size_t clusters;
uint32_t sector;
struct pcb* pcb = get_pcb_ptr();
struct file_desc* fdesc = &pcb->file_desc_array[fd];
uint32_t cluster_seq = fdesc->file_pos >> (9 + log2_sectors_per_cluster);
uint32_t cluster = ((uint32_t)fdesc->f32_dentry.cluster_high << 16) | fdesc->f32_dentry.cluster_low;
/* validate starting position isn't past end of file */
if (fdesc->file_pos >= fdesc->f32_dentry.file_size){
return 0;
}
/* validate final pos isn't past end of file */
if (fdesc->file_pos+nbytes > fdesc->f32_dentry.file_size){
nbytes = fdesc->f32_dentry.file_size - fdesc->file_pos;
}
// This can stay for now, as long as cluster_seq is correct.
for (i = 0; i < cluster_seq; i++) {
cluster = fat32_next_cluster(cluster);
}
clusters = nbytes >> (9 + log2_sectors_per_cluster);
/* Handle first unaligned block */
offset = fdesc->file_pos % 512; // This is the offset into the sector, not the cluster
leftover_length = 512 - offset;
sector = (fdesc->file_pos >> 9) & (sectors_per_cluster-1);
if (leftover_length != 0) {
if (nbytes <= leftover_length) {
fat32_read_sector(cluster, sector, sd_buf);
memcpy(buf, sd_buf + offset, nbytes);
bytes_read += nbytes;
fdesc->file_pos += bytes_read;
return bytes_read;
} else {
fat32_read_sector(cluster, sector, sd_buf);
memcpy(buf, sd_buf + offset, leftover_length);
bytes_read += leftover_length;
fdesc->file_pos += bytes_read;
}
}
/* Handle middle aligned blocks */
for (i = 0; i < clusters; i++) {
cluster = fat32_next_cluster(cluster);
if (cluster >= 0xffffff00) {
// cprintf("Last cluster in file!\n");
}
if (nbytes - bytes_read > 512) {
leftover_length = 512;
} else {
leftover_length = nbytes - bytes_read;
}
fat32_read_sector(cluster, cluster, sd_buf);
memcpy((uint8_t*)buf+bytes_read, sd_buf, leftover_length);
bytes_read += leftover_length;
fdesc->file_pos += bytes_read;
if (bytes_read == nbytes) {
return bytes_read;
}
}
return bytes_read;
}
// Read the sector offset from a given cluster into buf
// Why do we need this though, this is just doing a single multiplication?
// No, it is also doing an addition
int8_t fat32_read_sector(uint32_t cluster, uint32_t sector, void* buf) {
uint8_t error;
uint32_t addr = (cluster - 2) * sectors_per_cluster + sector + data_start_sector;
SD_readSingleBlock(addr, buf, &error);
return error;
}
// This will not handle clusters numbers that leaves a sector
uint32_t fat32_next_cluster(uint32_t cluster) {
uint8_t error;
uint32_t addr = fat_start_sector;
uint32_t cluster_val;
SD_readSingleBlock(addr, sd_buf, &error);
cluster_val = ((uint32_t*)sd_buf)[cluster];
return cluster_val;
}
int8_t fat32_get_cluster_by_name(const char* name, struct fat32_directory_entry* dentry) {
struct fat32_directory_entry* local_entry;
int i = 0;
uint32_t cluster;
cluster = fat32_next_cluster(root_cluster);
cprintf("Sectors per cluster: %hhx\n", sectors_per_cluster);
fat32_read_sector(root_cluster, 0, sd_buf);
for (i = 0; i < 16; i++){
local_entry = (struct fat32_directory_entry*)(sd_buf + i*32);
if (local_entry->attr1 == 0xf || local_entry->attr1 & 0x8 || !local_entry->attr1) {
continue;
}
cprintf("Name: %.11s\n", local_entry->file_name, local_entry->file_ext);
if (!strncmp(local_entry->file_name, name, 11)) {
i = -1;
break;
}
}
if (i != -1) {
cprintf("Failed to find file.\n");
return -1;
}
cprintf("Found file!\n");
memcpy(dentry, local_entry, 32);
return 0;
}

View File

@@ -1,22 +0,0 @@
#ifndef _FS_H
#define _FS_H
#include <stdint.h>
#include <stdio.h>
#include <process/process.h>
/* syscalls for files */
size_t file_read(int8_t fd, void* buf, size_t nbytes);
size_t file_write(int8_t fd, const void* buf, size_t nbytes);
int8_t file_open(const char* filename);
int8_t file_close(int8_t fd);
/* syscalls for directories */
size_t directory_read(int8_t fd, void* buf, size_t nbytes);
size_t directory_write(int8_t fd, const void* buf, size_t nbytes);
int8_t directory_open(const char* filename);
int8_t directory_close(int8_t fd);
#endif

View File

@@ -1,16 +0,0 @@
#ifndef _INTERRUPT_H
#define _INTERRUPT_H
#include <stdint.h>
#define BUTTON (1 << 0)
#define UART (1 << 1)
void init_interrupts();
void register_irq(void* addr, uint8_t irqn);
uint8_t irq_get_status();
void irq_set_status(uint8_t);
#endif

View File

@@ -1,76 +0,0 @@
.MACPACK generic
.autoimport
.import _enable_irq
.import _map
.export irq_int, nmi_int
.export _register_irq
.export _init_interrupts
IRQ_CMD_ADDR = $effc
IRQ_DAT_ADDR = $effd
IRQ_CMD_READIRQ = $00
; void init_interrupts();
; remap the upper page into ram,
; then load the new vector addresses.
.proc _init_interrupts
; map(001f, f);
lda #$1f
jsr pushax
lda #$f
jsr _map
lda #<irq_int
sta $fffe
lda #>irq_int
sta $ffff
lda #<nmi_int
sta $fffa
lda #>nmi_int
sta $fffb
rts
.endproc
.proc nmi_int
rti
.endproc
; irq_int
.proc irq_int
; Load IRQ number
lda #IRQ_CMD_READIRQ
sta IRQ_CMD_ADDR
lda IRQ_DAT_ADDR
; shift by 2 (oh so only 128 interrupts are supported lol)
asl
tax
jmp (irq_table,x)
; use that to index jump table
.endproc
; void register_irq(void* addr, uint8_t irqn);
.proc _register_irq
asl
tax
jsr popa
sta irq_table,x
jsr popa
sta irq_table+1,x
lda #$00
jsr pusha
txa
lsr
jsr _enable_irq
rts
.endproc
.data
; interrupt handler jump table
irq_table: .res 256

View File

@@ -1,11 +0,0 @@
#include <stdint.h>
#include <conio.h>
#include "interrupts/interrupt.h"
#include "devices/uart.h"
void handle_irq() {
}

View File

@@ -1,71 +0,0 @@
#include <conio.h>
#include <string.h>
#include "devices/interrupt_controller.h"
#include "interrupts/interrupt.h"
#include "devices/mapper.h"
#include "devices/rtc.h"
#include "devices/serial.h"
#include "devices/terminal.h"
#include "filesystems/fat32.h"
void handle_rtc_interrupt() {
// cputs("In IRQ interrupt!\n");
// cputc('A');
send_eoi();
asm volatile ("rti");
}
char buf[128];
int main() {
int8_t fd;
size_t nbytes, i;
cputs("Kernel\n");
cputs("Init Mapper\n");
init_mapper();
cputs("Initialize Interrupts\n");
init_interrupts();
cputs("Initialize Interrupt Controller\n");
init_interrupt_controller();
cputs("Initialize RTC\n");
init_rtc();
register_irq(&handle_rtc_interrupt, 0);
rtc_set(0xaaaa, RTC_THRESHOLD);
rtc_set(0xbbbb, RTC_IRQ_THRESHOLD);
asm volatile("cli");
cputs("Initialize Serial\n");
serial_init();
serial_puts("Hello from serial!\n");
fat32_init();
/* This is what is going to be part of open */
fd = fat32_file_open("VERYLA~1TXT");
cprintf("fd: %x\n", fd);
nbytes = fat32_file_read(fd, buf, 23);
for (i = 0; i < nbytes; i++) {
cprintf("%c", buf[i]);
}
while ((nbytes = fat32_file_read(fd, buf, 128))){
for (i = 0; i < nbytes; i++) {
cprintf("%c", buf[i]);
}
}
return 0;
}

View File

@@ -1,48 +0,0 @@
MEMORY
{
ZP: start = $0, size = $100, type = rw, define = yes;
STACK: start = $200, size = $E00, type = rw, define = yes;
KERNEL: start = $1000, size = $7000, type = rw, define = yes, file = %O;
USER: start = $8000, size = $6000, type = rw, define = yes;
IO: start = $E000, size = $1000, type = rw, define = yes;
ROM: start = $f000, size = $1000, type = rw, define = yes; #rw for vectors
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
STARTUP: load = KERNEL, type = ro;
ONCE: load = KERNEL, type = ro, optional = yes;
CODE: load = KERNEL, type = ro;
RODATA: load = KERNEL, type = ro;
DATA: load = KERNEL, type = rw, define = yes;
BSS: load = KERNEL, type = rw, define = yes;
HEAP: load = KERNEL, type = rw, define = yes, optional = yes;
}
FILES
{
%O: format = o65;
}
FORMATS
{
o65: os = super, version = 0, type = small,
export = _init;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
__STACKSIZE__: value = $0200, type = weak;
__STACKSTART__: type = weak, value = $0800;
}

View File

@@ -1,9 +0,0 @@
#include <process/process.h>
struct pcb fake_pcb;
//TODO
struct pcb* get_pcb_ptr() {
return &fake_pcb;
}

View File

@@ -1,46 +0,0 @@
#ifndef _PROCESS_H
#define _PROCESS_H
#include <stdint.h>
#include <filesystems/fat32.h>
#include <stdio.h>
#define FILE_DESC_SIZE 8
#define IN_USE 1
struct fops {
int8_t (*open)(const char* filename);
int8_t (*close)(int8_t fd);
size_t (*read)(int8_t fd, void* buf, size_t nbytes);
size_t (*write)(int8_t fd, const void* buf, size_t nbytes);
};
struct file_desc {
struct fops* file_ops;
uint8_t fs_type;
union {
struct fat32_directory_entry f32_dentry;
};
uint32_t file_pos;
uint32_t flags;
};
/* Process Control Block struct */
struct pcb {
struct file_desc file_desc_array[FILE_DESC_SIZE];
int32_t is_vidmapped;
uint8_t args[128];
uint16_t execute_return;
uint16_t pid;
uint16_t parent_pid;
uint16_t parent_esp;
};
struct pcb* get_pcb_ptr();
#endif

View File

@@ -1,19 +0,0 @@
DEVICE=/dev/mmcblk0
TMPMOUNT=/tmp/sd
FSDIR=../fsdir
V=-v
echo "$(tput bold setaf 11)Mounting Device$(tput sgr 0)"
mkdir $V -p $TMPMOUNT
sudo mount $V $DEVICE $TMPMOUNT
echo
echo "$(tput bold setaf 11)Copying Files$(tput sgr 0)"
sudo cp $V -r $FSDIR/* $TMPMOUNT
echo
echo "$(tput bold setaf 11)Unmounting Device$(tput sgr 0)"
sudo umount $V $DEVICE
rmdir $V $TMPMOUNT
echo

View File

@@ -1,38 +0,0 @@
#!/bin/bash
BOOTLOADER=$REPO_TOP/sw/bios/bootloader.bin
FILE=$REPO_TOP/sw/script/fs.fat
TMPMOUNT=/tmp/lo
FSDIR=$REPO_TOP/sw/fsdir
MNT=/run/media/$USER/SUPER6502
V=-v
# Smallest number of blocks where mkfs doesn't complain
BLOCKS=33296
rm $FILE
echo "$(tput bold setaf 11)Creating Filesystem$(tput sgr 0)"
mkfs.vfat $V -I -F32 -C $FILE -n SUPER6502 $BLOCKS
echo
echo "$(tput bold setaf 11)Modifying Boot Sector$(tput sgr 0)"
dd if=$BOOTLOADER of=$FILE bs=1 conv=notrunc count=11 $STATUS
dd if=$BOOTLOADER of=$FILE bs=1 conv=notrunc count=380 seek=71 skip=71 $STATUS
LOOP=$(udisksctl loop-setup -f $FILE | grep -o "/dev/loop\([0-9]\)\+")
MNT=$(udisksctl mount -b $LOOP $TMPMOUNT | grep -o "\([A-Za-z/-]*/\)SUPER6502")
echo "$(tput bold setaf 11)Copying Files$(tput sgr 0)"
cp $V -r $FSDIR/* $MNT
echo
udisksctl unmount -b $LOOP
udisksctl loop-delete -b $LOOP
echo "$(tput bold setaf 10)Done!$(tput sgr 0)"

View File

@@ -1,20 +0,0 @@
#!/bin/bash
BOOTLOADER=$REPO_TOP/sw/bios/bootloader.bin
DEVICE=/dev/mmcblk0
TMPBOOTSECT=/tmp/bootsect
TMPMOUNT=/tmp/sd
V=-v
# STATUS="status=none"
STATUS=
echo "$(tput bold setaf 11)Creating Filesystem$(tput sgr 0)"
sudo mkfs.vfat -I -F32 $DEVICE -n SUPER6502 $V
echo
echo "$(tput bold setaf 11)Modifying Boot Sector$(tput sgr 0)"
sudo dd if=$BOOTLOADER of=$DEVICE bs=1 count=11 $STATUS
sudo dd if=$BOOTLOADER of=$DEVICE bs=1 count=380 seek=71 skip=71 $STATUS
echo "$(tput bold setaf 10)Done!$(tput sgr 0)"

View File

@@ -1,108 +0,0 @@
#!/usr/bin/python
import sys
import io
class O65():
header: dict[str, int] = {}
options: list[(int, int, bytes)] = []
text: bytes
data: bytes
undef_ref_cnt: int
text_reloc: list[(int, int, int)] = []
data_reloc: list[(int, int, int)] = []
exports: list[(str, int, int)] = []
def __init__(self, filename: str) -> None:
with open(filename, "rb") as _file:
self.header["no_c64"] = int.from_bytes(_file.read(2))
self.header["magic"] = int.from_bytes(_file.read(3))
self.header["version"] = int.from_bytes(_file.read(1))
self.header["mode"] = int.from_bytes(_file.read(2), byteorder="little")
self.header["tbase"] = int.from_bytes(_file.read(2), byteorder="little")
self.header["tlen"] = int.from_bytes(_file.read(2), byteorder="little")
self.header["dbase"] = int.from_bytes(_file.read(2), byteorder="little")
self.header["dlen"] = int.from_bytes(_file.read(2), byteorder="little")
self.header["bbase"] = int.from_bytes(_file.read(2), byteorder="little")
self.header["blen"] = int.from_bytes(_file.read(2), byteorder="little")
self.header["zbase"] = int.from_bytes(_file.read(2), byteorder="little")
self.header["zlen"] = int.from_bytes(_file.read(2), byteorder="little")
self.header["stack"] = int.from_bytes(_file.read(2), byteorder="little")
olen = int.from_bytes(_file.read(1))
while olen != 0:
otype = int.from_bytes(_file.read(1))
obytes = _file.read(olen - 2)
self.options.append((olen, otype, obytes))
olen = int.from_bytes(_file.read(1))
text_offs = _file.tell()
print(f"Text offset: {text_offs}")
self.text = _file.read(self.header["tlen"])
self.data = _file.read(self.header["dlen"])
self.undef_ref_cnt = _file.read(2)
self.text_reloc = self._parse_reloc(_file)
self.data_reloc = self._parse_reloc(_file)
export_count = int.from_bytes(_file.read(2), byteorder="little")
for _ in range(export_count):
name: bytearray = bytearray()
data = 0
while True:
data = _file.read(1)
if data != b"\x00":
name.extend(data)
else:
break
segment = int.from_bytes(_file.read(1))
value = int.from_bytes(_file.read(2), byteorder="little")
self.exports.append((name.decode(), segment, value))
def _parse_reloc(self, fd: io.BufferedReader) -> list[(int, int, int)]:
reloc: list[(int, int, int)] = []
offset = fd.read(1)
while offset != b'\x00':
offset_val = 0
while offset == b'\xff':
offset = fd.read(1)
offset_val += int.from_bytes(offset) - 1
offset_val += int.from_bytes(offset)
typebyte = int.from_bytes(fd.read(1))
lobyte = None
if typebyte & 0x40:
lobyte = int.from_bytes(fd.read(1))
reloc.append((offset_val, typebyte, lobyte))
offset = fd.read(1)
return reloc
def main() -> None:
if len(sys.argv) < 2:
print("Please supply a filename")
return
filename = sys.argv[1]
print(filename)
o65 = O65(filename)
for item, value in o65.header.items():
print(f"{item}:\t{value:#x}")
total_olen = 0
for option in o65.options:
print(f"Length: {option[0]:#x} Type: {option[1]:#x}, Data: {option[2]}")
total_olen += option[0]
print(f"Total option length: {total_olen:#x}")
print(f"Text size: {len(o65.text)}")
print(f"Data size: {len(o65.data)}")
for item in o65.exports:
print(f"Name: {item[0]} Addr: {item[2]:#x}")
if __name__ == "__main__":
main()

View File

@@ -1,42 +0,0 @@
CC=../../cc65/bin/cl65
LD=../../cc65/bin/cl65
CFLAGS=-T -t none -I. --cpu "65C02"
LDFLAGS=-C link.ld -m $(NAME).map
NAME=devices_setup_test
DEVICES=$(REPO_TOP)/sw/kernel/devices
BIN=$(NAME).bin
HEX=$(NAME).hex
LISTS=lists
SRCS=$(wildcard *.s) $(wildcard *.c)
SRCS+=$(DEVICES)/rtc.s $(DEVICES)/interrupt_controller.s
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
# Make sure the kernel linked to correct address, no relocation!
all: $(HEX)
$(HEX): $(BIN)
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
%.o: %.c $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
%.o: %.s $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
$(LISTS):
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
.PHONY: clean
clean:
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map

View File

@@ -1,35 +0,0 @@
MEMORY
{
ZP: start = $0, size = $100, type = rw, define = yes;
SDRAM: start = $9200, size = $4d00, type = rw, define = yes;
ROM: start = $F000, size = $1000, file = %O;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
DATA: load = ROM, type = rw, define = yes, run = SDRAM;
BSS: load = SDRAM, type = bss, define = yes;
HEAP: load = SDRAM, type = bss, optional = yes;
STARTUP: load = ROM, type = ro;
ONCE: load = ROM, type = ro, optional = yes;
CODE: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
VECTORS: load = ROM, type = ro, start = $FFFA;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
# Define the stack size for the application
__STACKSIZE__: value = $0200, type = weak;
__STACKSTART__: type = weak, value = $0800; # 2k stack
}

View File

@@ -1,39 +0,0 @@
.export _init, nmi_int, irq_int
.autoimport
.import _init_interrupt_controller
.import _init_rtc
.zeropage
finish: .res 1
.code
nmi_int:
irq_int:
lda #$6d
sta $00
_init:
ldx #$ff
txs
LDA #<(__STACKSTART__ + __STACKSIZE__)
STA sp
LDA #>(__STACKSTART__ + __STACKSIZE__)
STA sp+1
jsr _init_interrupt_controller
jsr _init_rtc
; enable interrupt 0
lda #$00
jsr pusha
lda #$0
jsr _enable_irq
cli
@end: bra @end

View File

@@ -1,14 +0,0 @@
; ---------------------------------------------------------------------------
; vectors.s
; ---------------------------------------------------------------------------
;
; Defines the interrupt vector table.
.import _init
.import nmi_int, irq_int
.segment "VECTORS"
.addr nmi_int ; NMI vector
.addr _init ; Reset vector
.addr irq_int ; IRQ/BRK vector

View File

@@ -1,49 +0,0 @@
CC=../../cc65/bin/cl65
LD=../../cc65/bin/cl65
SIM=../../cc65/bin/sim65
CFLAGS=-T -t sim65c02 -I. -I $(REPO_TOP)/sw/kernel
LDFLAGS=-m $(NAME).map
NAME=fs_test
SIMARGS=
BIN=$(NAME).bin
FS=$(REPO_TOP)/sw/script/fs.fat
LISTS=lists
EXT_SRCS=$(REPO_TOP)/sw/kernel/filesystems/fat32.s $(REPO_TOP)/sw/kernel/filesystems/fat32_c.c
SRCS=$(wildcard *.s) $(wildcard *.c)
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
SRCS+=$(EXT_SRCS)
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
run: all
$(SIM) $(SIMARGS) $(BIN)
all: fs.fat $(BIN)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
%.o: %.c $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
%.o: %.s $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
fs.fat: $(FS)
cp $^ .
$(LISTS):
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
.PHONY: clean
clean:
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map

View File

@@ -1,5 +0,0 @@
.import _printf
.export _cprintf
_cprintf:
jmp _printf

View File

@@ -1,32 +0,0 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <process/process.h>
#define FILE_PATH "fs.fat"
struct pcb fake_pcb;
//TODO
struct pcb* get_pcb_ptr() {
return &fake_pcb;
}
uint32_t lmulii(uint16_t a, uint16_t b) {
printf("lmulii: %x * %x = %x\n", a, b, a*b);
return a * b;
}
uint16_t imulii(uint16_t a, uint16_t b) {
printf("imulii: %x * %x = %x\n", a, b, a*b);
return a * b;
}
uint8_t SD_readSingleBlock(uint32_t addr, uint8_t *buf, uint8_t *error) {
FILE* f = fopen(FILE_PATH, "rb");
(void)error;
fseek(f, addr * 512, SEEK_SET);
fread(buf, 512, 1, f);
fclose(f);
return 0;
}

View File

@@ -1,31 +0,0 @@
#include <stdio.h>
#include <filesystems/fat32.h>
#include <conio.h>
void fat32_init(void);
char data [256];
int main(void) {
int8_t fd;
size_t i;
size_t nbytes;
fat32_init();
cprintf("log2 sectors per cluster: %x\n", log2_sectors_per_cluster);
/* This is what is going to be part of open */
fd = fat32_file_open("VERYLA~1TXT");
cprintf("fd: %x\n", fd);
nbytes = fat32_file_read(fd, data, 123);
for (i = 0; i < nbytes; i++) {
cprintf("%c", data[i]);
}
while ((nbytes = fat32_file_read(fd, data, 256))){
for (i = 0; i < nbytes; i++) {
cprintf("%c", data[i]);
}
}
}

View File

@@ -1,39 +0,0 @@
CC=../../cc65/bin/cl65
LD=../../cc65/bin/cl65
CFLAGS=-T -t none -I. --cpu "65C02"
LDFLAGS=-C link.ld -m $(NAME).map
NAME=indirect_test
BIN=$(NAME).bin
HEX=$(NAME).hex
LISTS=lists
SRCS=$(wildcard *.s) $(wildcard *.c)
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
# Make sure the kernel linked to correct address, no relocation!
all: $(HEX)
$(HEX): $(BIN)
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
%.o: %.c $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
%.o: %.s $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
$(LISTS):
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
.PHONY: clean
clean:
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map

View File

@@ -1,35 +0,0 @@
MEMORY
{
ZP: start = $0, size = $100, type = rw, define = yes;
SDRAM: start = $9200, size = $4d00, type = rw, define = yes;
ROM: start = $F000, size = $1000, file = %O;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
DATA: load = ROM, type = rw, define = yes, run = SDRAM;
BSS: load = SDRAM, type = bss, define = yes;
HEAP: load = SDRAM, type = bss, optional = yes;
STARTUP: load = ROM, type = ro;
ONCE: load = ROM, type = ro, optional = yes;
CODE: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
VECTORS: load = ROM, type = ro, start = $FFFA;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
# Define the stack size for the application
__STACKSIZE__: value = $0200, type = weak;
__STACKSTART__: type = weak, value = $0800; # 2k stack
}

View File

@@ -1,20 +0,0 @@
.export _init, _nmi_int, _irq_int
.code
_nmi_int:
_irq_int:
_init:
ldx #$ff
txs
lda #$aa
sta $01
lda #$bb
sta $00
ldy #$1
lda #$cc
sta ($00),y
@end: bra @end

View File

@@ -1,14 +0,0 @@
; ---------------------------------------------------------------------------
; vectors.s
; ---------------------------------------------------------------------------
;
; Defines the interrupt vector table.
.import _init
.import _nmi_int, _irq_int
.segment "VECTORS"
.addr _nmi_int ; NMI vector
.addr _init ; Reset vector
.addr _irq_int ; IRQ/BRK vector

View File

@@ -1,39 +0,0 @@
CC=../../cc65/bin/cl65
LD=../../cc65/bin/cl65
CFLAGS=-T -t none -I. --cpu "65C02"
LDFLAGS=-C link.ld -m $(NAME).map
NAME=irq_test
BIN=$(NAME).bin
HEX=$(NAME).hex
LISTS=lists
SRCS=$(wildcard *.s) $(wildcard *.c)
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
# Make sure the kernel linked to correct address, no relocation!
all: $(HEX)
$(HEX): $(BIN)
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
%.o: %.c $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
%.o: %.s $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
$(LISTS):
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
.PHONY: clean
clean:
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map

View File

@@ -1,35 +0,0 @@
MEMORY
{
ZP: start = $0, size = $100, type = rw, define = yes;
SDRAM: start = $9200, size = $4d00, type = rw, define = yes;
ROM: start = $F000, size = $1000, file = %O;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
DATA: load = ROM, type = rw, define = yes, run = SDRAM;
BSS: load = SDRAM, type = bss, define = yes;
HEAP: load = SDRAM, type = bss, optional = yes;
STARTUP: load = ROM, type = ro;
ONCE: load = ROM, type = ro, optional = yes;
CODE: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
VECTORS: load = ROM, type = ro, start = $FFFA;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
# Define the stack size for the application
__STACKSIZE__: value = $0200, type = weak;
__STACKSTART__: type = weak, value = $0800; # 2k stack
}

View File

@@ -1,70 +0,0 @@
.MACPACK generic
.export _init, _nmi_int, _irq_int
.importzp tmp1
CMD = $effc
DAT = $effd
.zeropage
finish: .res 1
curr_irq: .res 1
.code
_nmi_int:
_irq_int:
; We should have triggered interrupt 1
stz CMD
lda DAT
cmp curr_irq
bne @bad
lda #$ff
sta CMD
lda #$1
sta DAT
inc curr_irq
beq @good
cli
rti
@good:
lda #$6d
sta finish
@bad:
lda #$bd
sta finish
_init:
ldx #$ff
txs
ldx #$20 ; enable
ldy #$ff
jsr cmd_all
ldx #$40 ; edge type
ldy #$00
jsr cmd_all
stz curr_irq
cli
jmp wait
cmd_all:
txa
add #$10
sta tmp1
loop:
txa
sta CMD
tya
sta DAT
inx
cpx tmp1
blt loop
rts
wait:
bra wait

View File

@@ -1,14 +0,0 @@
; ---------------------------------------------------------------------------
; vectors.s
; ---------------------------------------------------------------------------
;
; Defines the interrupt vector table.
.import _init
.import _nmi_int, _irq_int
.segment "VECTORS"
.addr _nmi_int ; NMI vector
.addr _init ; Reset vector
.addr _irq_int ; IRQ/BRK vector

View File

@@ -1,39 +0,0 @@
CC=../../cc65/bin/cl65
LD=../../cc65/bin/cl65
CFLAGS=-T -t none -I. --cpu "65C02"
LDFLAGS=-C link.ld -m $(NAME).map
NAME=jsr_test
BIN=$(NAME).bin
HEX=$(NAME).hex
LISTS=lists
SRCS=$(wildcard *.s) $(wildcard *.c)
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
# Make sure the kernel linked to correct address, no relocation!
all: $(HEX)
$(HEX): $(BIN)
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
%.o: %.c $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
%.o: %.s $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
$(LISTS):
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
.PHONY: clean
clean:
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map

View File

@@ -1,35 +0,0 @@
MEMORY
{
ZP: start = $0, size = $100, type = rw, define = yes;
SDRAM: start = $9200, size = $4d00, type = rw, define = yes;
ROM: start = $F000, size = $1000, file = %O;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
DATA: load = ROM, type = rw, define = yes, run = SDRAM;
BSS: load = SDRAM, type = bss, define = yes;
HEAP: load = SDRAM, type = bss, optional = yes;
STARTUP: load = ROM, type = ro;
ONCE: load = ROM, type = ro, optional = yes;
CODE: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
VECTORS: load = ROM, type = ro, start = $FFFA;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
# Define the stack size for the application
__STACKSIZE__: value = $0200, type = weak;
__STACKSTART__: type = weak, value = $0800; # 2k stack
}

View File

@@ -1,23 +0,0 @@
.export _init, _nmi_int, _irq_int
.code
_nmi_int:
_irq_int:
_init:
ldx #$ff
txs
lda #$00
jsr subroutine
sta $00
@1: bra @1
subroutine:
inc
jsr suborutine2
rts
suborutine2:
inc
rts

View File

@@ -1,14 +0,0 @@
; ---------------------------------------------------------------------------
; vectors.s
; ---------------------------------------------------------------------------
;
; Defines the interrupt vector table.
.import _init
.import _nmi_int, _irq_int
.segment "VECTORS"
.addr _nmi_int ; NMI vector
.addr _init ; Reset vector
.addr _irq_int ; IRQ/BRK vector

View File

@@ -1,39 +0,0 @@
CC=../../cc65/bin/cl65
LD=../../cc65/bin/cl65
CFLAGS=-T -t none -I. --cpu "65C02"
LDFLAGS=-C link.ld -m $(NAME).map
NAME=loop_test
BIN=$(NAME).bin
HEX=$(NAME).hex
LISTS=lists
SRCS=$(wildcard *.s) $(wildcard *.c)
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
# Make sure the kernel linked to correct address, no relocation!
all: $(HEX)
$(HEX): $(BIN)
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
%.o: %.c $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
%.o: %.s $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
$(LISTS):
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
.PHONY: clean
clean:
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map

View File

@@ -1,35 +0,0 @@
MEMORY
{
ZP: start = $0, size = $100, type = rw, define = yes;
SDRAM: start = $9200, size = $4d00, type = rw, define = yes;
ROM: start = $F000, size = $1000, file = %O;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
DATA: load = ROM, type = rw, define = yes, run = SDRAM;
BSS: load = SDRAM, type = bss, define = yes;
HEAP: load = SDRAM, type = bss, optional = yes;
STARTUP: load = ROM, type = ro;
ONCE: load = ROM, type = ro, optional = yes;
CODE: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
VECTORS: load = ROM, type = ro, start = $FFFA;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
# Define the stack size for the application
__STACKSIZE__: value = $0200, type = weak;
__STACKSTART__: type = weak, value = $0800; # 2k stack
}

View File

@@ -1,16 +0,0 @@
.export _init, _nmi_int, _irq_int
.code
_nmi_int:
_irq_int:
_init:
lda #$00
@1: inc
sta $01
lda $01
cmp $01
beq @1
@end: bra @end

View File

@@ -1,14 +0,0 @@
; ---------------------------------------------------------------------------
; vectors.s
; ---------------------------------------------------------------------------
;
; Defines the interrupt vector table.
.import _init
.import _nmi_int, _irq_int
.segment "VECTORS"
.addr _nmi_int ; NMI vector
.addr _init ; Reset vector
.addr _irq_int ; IRQ/BRK vector

View File

@@ -1,39 +0,0 @@
CC=../../cc65/bin/cl65
LD=../../cc65/bin/cl65
CFLAGS=-T -t none -I. --cpu "65C02"
LDFLAGS=-C link.ld -m $(NAME).map
NAME=mapper_test
BIN=$(NAME).bin
HEX=$(NAME).hex
LISTS=lists
SRCS=$(wildcard *.s) $(wildcard *.c)
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
# Make sure the kernel linked to correct address, no relocation!
all: $(HEX)
$(HEX): $(BIN)
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
%.o: %.c $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
%.o: %.s $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
$(LISTS):
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
.PHONY: clean
clean:
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map

View File

@@ -1,35 +0,0 @@
MEMORY
{
ZP: start = $0, size = $100, type = rw, define = yes;
SDRAM: start = $9200, size = $4d00, type = rw, define = yes;
ROM: start = $F000, size = $1000, file = %O;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
DATA: load = ROM, type = rw, define = yes, run = SDRAM;
BSS: load = SDRAM, type = bss, define = yes;
HEAP: load = SDRAM, type = bss, optional = yes;
STARTUP: load = ROM, type = ro;
ONCE: load = ROM, type = ro, optional = yes;
CODE: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
VECTORS: load = ROM, type = ro, start = $FFFA;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
# Define the stack size for the application
__STACKSIZE__: value = $0200, type = weak;
__STACKSTART__: type = weak, value = $0800; # 2k stack
}

View File

@@ -1,64 +0,0 @@
.export _init, _nmi_int, _irq_int
.code
_nmi_int:
_irq_int:
MAPPER_BASE = $200
_init:
ldx #$ff
txs
lda #$10
sta MAPPER_BASE + 2
; This should store 0x55aa to memory $010000, instead of $001000
lda #$aa
sta $1000
lda #$55
sta $1001
lda #$01
sta MAPPER_BASE + 2
; This should store 0xddcc to memory $001000
lda #$cc
sta $1000
lda #$dd
sta $1001
lda #$10
sta MAPPER_BASE + 2
lda $1000
cmp #$aa
bne @bad
lda $1001
cmp #$55
bne @bad
lda #$01
sta MAPPER_BASE + 2
lda $1000
cmp #$cc
bne @bad
lda $1001
cmp #$dd
bne @bad
@end:
lda #$6d
sta $00
bra @end
@bad:
lda #$bd
sta $00
bra @bad

View File

@@ -1,14 +0,0 @@
; ---------------------------------------------------------------------------
; vectors.s
; ---------------------------------------------------------------------------
;
; Defines the interrupt vector table.
.import _init
.import _nmi_int, _irq_int
.segment "VECTORS"
.addr _nmi_int ; NMI vector
.addr _init ; Reset vector
.addr _irq_int ; IRQ/BRK vector

View File

@@ -1,39 +0,0 @@
CC=../../cc65/bin/cl65
LD=../../cc65/bin/cl65
CFLAGS=-T -t none -I. --cpu "65C02"
LDFLAGS=-C link.ld -m $(NAME).map
NAME=multiplier_test
BIN=$(NAME).bin
HEX=$(NAME).hex
LISTS=lists
SRCS=$(wildcard *.s) $(wildcard *.c)
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
# Make sure the kernel linked to correct address, no relocation!
all: $(HEX)
$(HEX): $(BIN)
objcopy --input-target=binary --output-target=verilog $(BIN) $(HEX)
$(BIN): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
%.o: %.c $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
%.o: %.s $(LISTS)
$(CC) $(CFLAGS) -l $(LISTS)/$<.list -c $< -o $@
$(LISTS):
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
.PHONY: clean
clean:
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map

View File

@@ -1,35 +0,0 @@
MEMORY
{
ZP: start = $0, size = $100, type = rw, define = yes;
SDRAM: start = $9200, size = $4d00, type = rw, define = yes;
ROM: start = $F000, size = $1000, file = %O;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp, define = yes;
DATA: load = ROM, type = rw, define = yes, run = SDRAM;
BSS: load = SDRAM, type = bss, define = yes;
HEAP: load = SDRAM, type = bss, optional = yes;
STARTUP: load = ROM, type = ro;
ONCE: load = ROM, type = ro, optional = yes;
CODE: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
VECTORS: load = ROM, type = ro, start = $FFFA;
}
FEATURES {
CONDES: segment = STARTUP,
type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__;
CONDES: segment = STARTUP,
type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__;
}
SYMBOLS {
# Define the stack size for the application
__STACKSIZE__: value = $0200, type = weak;
__STACKSTART__: type = weak, value = $0800; # 2k stack
}

View File

@@ -1,73 +0,0 @@
.MACPACK generic
.export _init, _nmi_int, _irq_int
MULTIPLIER_BASE = $eff0
MULTIPLIER_AL = MULTIPLIER_BASE + 0
MULTIPLIER_AH = MULTIPLIER_BASE + 1
MULTIPLIER_BL = MULTIPLIER_BASE + 2
MULTIPLIER_BH = MULTIPLIER_BASE + 3
MULTIPLIER_OLL = MULTIPLIER_BASE + 4
MULTIPLIER_OLH = MULTIPLIER_BASE + 5
MULTIPLIER_OHL = MULTIPLIER_BASE + 6
MULTIPLIER_OHH = MULTIPLIER_BASE + 7
GOLDEN_OUTPUT_0 = $03
GOLDEN_OUTPUT_1 = $0a
GOLDEN_OUTPUT_2 = $08
GOLDEN_OUTPUT_3 = $00
.zeropage
finish: .res 1
.data
output: .res 4
.code
_nmi_int:
_irq_int:
_init:
ldx #$ff
txs
lda #$01
sta MULTIPLIER_AL
lda #$02
sta MULTIPLIER_AH
lda #$03
sta MULTIPLIER_BL
lda #$04
sta MULTIPLIER_BH
ldx #$00
L1: lda MULTIPLIER_OLL,x
sta output,x
inx
cpx #$4
bne L1
lda output
cmp #GOLDEN_OUTPUT_0
bne fail
lda output+1
cmp #GOLDEN_OUTPUT_1
bne fail
lda output+2
cmp #GOLDEN_OUTPUT_2
bne fail
lda output+3
cmp #GOLDEN_OUTPUT_3
bne fail
lda #$6d
sta finish
fail:
lda #$bd
sta finish

Some files were not shown because too many files have changed in this diff Show More