Merge branch '15-parse-the-read-only-file-system' into 'master'

Resolve "Parse the read-only file system"

Closes #15

See merge request bslathi19/super6502!64
This commit is contained in:
Byron Lathi
2023-12-09 07:28:55 +00:00
23 changed files with 869 additions and 19 deletions

View File

@@ -140,6 +140,24 @@ mapper_code sim:
- TEST_PROGRAM_NAME=mapper_test make mapper_code_tb
- ./mapper_code_tb
multiplier_code sim:
tags:
- linux
- iverilog
stage: simulate
needs:
- job: build toolchain
artifacts: true
artifacts:
paths:
- hw/efinix_fpga/simulation/mapper_code_tb.vcd
script:
- source init_env.sh
- cd hw/efinix_fpga/simulation
- make clean
- TEST_PROGRAM_NAME=multiplier_test make mapper_code_tb
- ./mapper_code_tb
interrupt_controller sim:
tags:
- linux

Submodule sw/cc65 updated: 58518b6ff5...9824f6e3d4

1
sw/fsdir/test.txt Normal file
View File

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

View File

@@ -0,0 +1,33 @@
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

@@ -11,3 +11,20 @@ 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

@@ -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

View 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

View File

@@ -0,0 +1,53 @@
#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

@@ -0,0 +1,112 @@
.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

@@ -0,0 +1,207 @@
#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

@@ -0,0 +1,22 @@
#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

@@ -6,9 +6,10 @@
#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");
@@ -20,18 +21,21 @@ void handle_rtc_interrupt() {
char buf[128];
int main() {
int8_t fd;
size_t nbytes, i;
cputs("Kernel\n");
// cputs("Init Mapper\n");
cputs("Init Mapper\n");
init_mapper();
// cputs("Initialize Interrupts\n");
cputs("Initialize Interrupts\n");
init_interrupts();
// cputs("Initialize Interrupt Controller\n");
cputs("Initialize Interrupt Controller\n");
init_interrupt_controller();
// cputs("Initialize RTC\n");
cputs("Initialize RTC\n");
init_rtc();
register_irq(&handle_rtc_interrupt, 0);
@@ -41,22 +45,26 @@ int main() {
asm volatile("cli");
// cputs("Initialize Serial\n");
cputs("Initialize Serial\n");
serial_init();
serial_puts("Hello from serial!\n");
terminal_open(NULL);
terminal_write(0, "Terminal Write\n", 15);
fat32_init();
while(1) {
if (terminal_read(0, buf, 128)) {
cprintf("Fail\n");
break;
/* 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]);
}
terminal_write(0, "Got: ", 5);
terminal_write(0, buf, strlen(buf));
terminal_write(0, "\n", 1);
}
return 0;

View File

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

View File

@@ -0,0 +1,46 @@
#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

@@ -35,6 +35,4 @@ udisksctl unmount -b $LOOP
udisksctl loop-delete -b $LOOP
echo "$(tput bold setaf 11)Converting Image to Verilog$(tput sgr 0)"
objcopy --input-target=binary --output-target=verilog --verilog-data-width=1 $FILE $FILE.hex
echo "$(tput bold setaf 10)Done!$(tput sgr 0)"

View File

@@ -0,0 +1,49 @@
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

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

View File

@@ -0,0 +1,32 @@
#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

@@ -0,0 +1,31 @@
#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

@@ -0,0 +1,39 @@
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

@@ -0,0 +1,35 @@
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

@@ -0,0 +1,73 @@
.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

View File

@@ -0,0 +1,14 @@
; ---------------------------------------------------------------------------
; 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