Add some basic fat32 code
This commit is contained in:
@@ -10,4 +10,21 @@ SPI_BAUD = $efd8
|
|||||||
SPI_INPUT = $efd9
|
SPI_INPUT = $efd9
|
||||||
SPI_OUTPUT = $efda
|
SPI_OUTPUT = $efda
|
||||||
SPI_CTRL = $efdb
|
SPI_CTRL = $efdb
|
||||||
SPI_STATUS = SPI_CTRL
|
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
|
||||||
12
sw/kernel/devices/multiplier.h
Normal file
12
sw/kernel/devices/multiplier.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#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
|
||||||
36
sw/kernel/devices/multiplier.s
Normal file
36
sw/kernel/devices/multiplier.s
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
.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
|
||||||
34
sw/kernel/filesystems/fat32.h
Normal file
34
sw/kernel/filesystems/fat32.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef _FAT32_H
|
||||||
|
#define _FAT32_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void fat32_init();
|
||||||
|
|
||||||
|
struct fat32_directory_entry {
|
||||||
|
char file_name[8];
|
||||||
|
char file_ext[3];
|
||||||
|
uint8_t attr1;
|
||||||
|
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];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
115
sw/kernel/filesystems/fat32.s
Normal file
115
sw/kernel/filesystems/fat32.s
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
.MACPACK generic
|
||||||
|
|
||||||
|
.autoimport
|
||||||
|
.feature string_escapes
|
||||||
|
|
||||||
|
.importzp ptr1, sreg
|
||||||
|
|
||||||
|
.import _SD_readSingleBlock
|
||||||
|
|
||||||
|
.export _fat32_init
|
||||||
|
|
||||||
|
|
||||||
|
.data
|
||||||
|
fat_start_sector: .res 2
|
||||||
|
data_start_sector: .res 2
|
||||||
|
sd_buf: .res 512
|
||||||
|
|
||||||
|
bps_val_str: .asciiz "Bytes Per Sector: 0x%x\n"
|
||||||
|
sps_val_str: .asciiz "Sectors Per Cluster: 0x%x\n"
|
||||||
|
rsv_val_str: .asciiz "Reserved Sectors: 0x%x\n"
|
||||||
|
fat_count_str: .asciiz "FAT count: 0x%x\n"
|
||||||
|
fat_sect_str: .asciiz "Sectors per FAT: 0x%x\n"
|
||||||
|
fat_size_tot_str: .asciiz "Total fat size: 0x%lx\n"
|
||||||
|
rsv_sect_bytes_str: .asciiz "Total reserved bytes: 0x%x\n"
|
||||||
|
rsv_sd_sectors: .asciiz "Reserved SD Sectors: 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
|
||||||
|
|
||||||
|
.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 #<bps_val_str
|
||||||
|
ldx #>bps_val_str
|
||||||
|
jsr pushax
|
||||||
|
lda bytes_per_sector
|
||||||
|
ldx bytes_per_sector+1
|
||||||
|
jsr pushax
|
||||||
|
ldy #$4
|
||||||
|
jsr _printf
|
||||||
|
|
||||||
|
lda #<sps_val_str
|
||||||
|
ldx #>sps_val_str
|
||||||
|
jsr pushax
|
||||||
|
lda sectors_per_cluster
|
||||||
|
ldx #$00
|
||||||
|
jsr pushax
|
||||||
|
ldy #$4
|
||||||
|
jsr _cprintf
|
||||||
|
|
||||||
|
lda #<rsv_val_str
|
||||||
|
ldx #>rsv_val_str
|
||||||
|
jsr pushax
|
||||||
|
lda reserved_sectors
|
||||||
|
ldx #$00
|
||||||
|
jsr pushax
|
||||||
|
ldy #$4
|
||||||
|
jsr _cprintf
|
||||||
|
|
||||||
|
lda #<fat_count_str
|
||||||
|
ldx #>fat_count_str
|
||||||
|
jsr pushax
|
||||||
|
lda fat_count
|
||||||
|
ldx #$00
|
||||||
|
jsr pushax
|
||||||
|
ldy #$4
|
||||||
|
jsr _cprintf
|
||||||
|
|
||||||
|
|
||||||
|
lda #<rsv_sect_bytes_str
|
||||||
|
ldx #>rsv_sect_bytes_str
|
||||||
|
jsr pushax
|
||||||
|
|
||||||
|
lda reserved_sectors
|
||||||
|
jsr pusha0
|
||||||
|
lda bytes_per_sector
|
||||||
|
ldx bytes_per_sector+1
|
||||||
|
jsr _imulii
|
||||||
|
jsr pushax
|
||||||
|
ldy #$4
|
||||||
|
jsr _cprintf
|
||||||
|
|
||||||
|
lda #<fat_size_tot_str
|
||||||
|
ldx #>fat_size_tot_str
|
||||||
|
jsr pushax
|
||||||
|
|
||||||
|
; multiply fat size and number of fats
|
||||||
|
|
||||||
|
lda fat_count
|
||||||
|
jsr pusha0
|
||||||
|
lda sectors_per_fat
|
||||||
|
ldx sectors_per_fat+1
|
||||||
|
jsr _lmulii
|
||||||
|
jsr pusheax
|
||||||
|
ldy #$6
|
||||||
|
jsr _cprintf
|
||||||
|
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
19
sw/kernel/filesystems/fs.h
Normal file
19
sw/kernel/filesystems/fs.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef _FS_H
|
||||||
|
#define _FS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* syscalls for files */
|
||||||
|
int8_t file_read(int8_t fd, void* buf, int8_t nbytes);
|
||||||
|
int8_t file_write(int8_t fd, const void* buf, int8_t nbytes);
|
||||||
|
int8_t file_open(const uint8_t* filename);
|
||||||
|
int8_t file_close(int8_t fd);
|
||||||
|
|
||||||
|
/* syscalls for directories */
|
||||||
|
int8_t directory_read(int8_t fd, void* buf, int8_t nbytes);
|
||||||
|
int8_t directory_write(int8_t fd, const void* buf, int8_t nbytes);
|
||||||
|
int8_t directory_open(const uint8_t* filename);
|
||||||
|
int8_t directory_close(int8_t fd);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -6,9 +6,10 @@
|
|||||||
#include "devices/mapper.h"
|
#include "devices/mapper.h"
|
||||||
#include "devices/rtc.h"
|
#include "devices/rtc.h"
|
||||||
#include "devices/serial.h"
|
#include "devices/serial.h"
|
||||||
|
|
||||||
#include "devices/terminal.h"
|
#include "devices/terminal.h"
|
||||||
|
|
||||||
|
#include "filesystems/fat32.h"
|
||||||
|
|
||||||
|
|
||||||
void handle_rtc_interrupt() {
|
void handle_rtc_interrupt() {
|
||||||
// cputs("In IRQ interrupt!\n");
|
// cputs("In IRQ interrupt!\n");
|
||||||
@@ -22,16 +23,16 @@ char buf[128];
|
|||||||
int main() {
|
int main() {
|
||||||
cputs("Kernel\n");
|
cputs("Kernel\n");
|
||||||
|
|
||||||
// cputs("Init Mapper\n");
|
cputs("Init Mapper\n");
|
||||||
init_mapper();
|
init_mapper();
|
||||||
|
|
||||||
// cputs("Initialize Interrupts\n");
|
cputs("Initialize Interrupts\n");
|
||||||
init_interrupts();
|
init_interrupts();
|
||||||
|
|
||||||
// cputs("Initialize Interrupt Controller\n");
|
cputs("Initialize Interrupt Controller\n");
|
||||||
init_interrupt_controller();
|
init_interrupt_controller();
|
||||||
|
|
||||||
// cputs("Initialize RTC\n");
|
cputs("Initialize RTC\n");
|
||||||
init_rtc();
|
init_rtc();
|
||||||
|
|
||||||
register_irq(&handle_rtc_interrupt, 0);
|
register_irq(&handle_rtc_interrupt, 0);
|
||||||
@@ -41,10 +42,12 @@ int main() {
|
|||||||
|
|
||||||
asm volatile("cli");
|
asm volatile("cli");
|
||||||
|
|
||||||
// cputs("Initialize Serial\n");
|
cputs("Initialize Serial\n");
|
||||||
serial_init();
|
serial_init();
|
||||||
|
|
||||||
serial_puts("Hello from serial!\n");
|
serial_puts("Hello from serial!\n");
|
||||||
|
|
||||||
|
fat32_init();
|
||||||
|
|
||||||
terminal_open(NULL);
|
terminal_open(NULL);
|
||||||
terminal_write(0, "Terminal Write\n", 15);
|
terminal_write(0, "Terminal Write\n", 15);
|
||||||
|
|||||||
48
sw/test_code/fs_test/Makefile
Normal file
48
sw/test_code/fs_test/Makefile
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
CC=../../cc65/bin/cl65
|
||||||
|
LD=../../cc65/bin/cl65
|
||||||
|
SIM=../../cc65/bin/sim65
|
||||||
|
CFLAGS=-T -t sim65c02 -I.
|
||||||
|
LDFLAGS=-m $(NAME).map
|
||||||
|
|
||||||
|
NAME=fs_test
|
||||||
|
|
||||||
|
BIN=$(NAME).bin
|
||||||
|
|
||||||
|
FS=$(REPO_TOP)/sw/script/fs.fat
|
||||||
|
|
||||||
|
LISTS=lists
|
||||||
|
|
||||||
|
EXT_SRCS=$(REPO_TOP)/sw/kernel/filesystems/fat32.s
|
||||||
|
|
||||||
|
SRCS=$(wildcard *.s) $(wildcard *.c)
|
||||||
|
SRCS+=$(wildcard **/*.s) $(wildcard **/*.c)
|
||||||
|
OBJS+=$(patsubst %.s,%.o,$(filter %s,$(SRCS)))
|
||||||
|
OBJS+=$(patsubst %.c,%.o,$(filter %c,$(SRCS)))
|
||||||
|
|
||||||
|
run: all
|
||||||
|
$(SIM) $(BIN)
|
||||||
|
|
||||||
|
all: fs.fat fat32.s $(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 $@
|
||||||
|
|
||||||
|
fat32.s: $(EXT_SRCS)
|
||||||
|
cp $^ .
|
||||||
|
|
||||||
|
fs.fat: $(FS)
|
||||||
|
cp $^ .
|
||||||
|
|
||||||
|
$(LISTS):
|
||||||
|
mkdir -p $(addprefix $(LISTS)/,$(sort $(dir $(SRCS))))
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf $(OBJS) $(BIN) $(HEX) $(LISTS) $(NAME).map fat32.s
|
||||||
|
|
||||||
5
sw/test_code/fs_test/asm_harness.s
Normal file
5
sw/test_code/fs_test/asm_harness.s
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.import _printf
|
||||||
|
.export _cprintf
|
||||||
|
|
||||||
|
_cprintf:
|
||||||
|
jmp _printf
|
||||||
21
sw/test_code/fs_test/harness.c
Normal file
21
sw/test_code/fs_test/harness.c
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define FILE_PATH "fs.fat"
|
||||||
|
|
||||||
|
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");
|
||||||
|
// fseek(f, addr * 512, SEEK_SET);
|
||||||
|
fread(buf, 512, 1, f);
|
||||||
|
}
|
||||||
9
sw/test_code/fs_test/main.c
Normal file
9
sw/test_code/fs_test/main.c
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void fat32_init(void);
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
printf("Hello, world!\n");
|
||||||
|
fat32_init();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user