Implement disk controller

This commit is contained in:
Ry 2022-10-23 22:36:24 -07:00
parent 5bfe275b29
commit 7004b61606
5 changed files with 140 additions and 3 deletions

View File

@ -5,6 +5,7 @@ TARGET=fox32
CFILES = src/main.c \ CFILES = src/main.c \
src/bus.c \ src/bus.c \
src/cpu.c \ src/cpu.c \
src/disk.c \
src/framebuffer.c \ src/framebuffer.c \
src/mouse.c \ src/mouse.c \
src/screen.c src/screen.c

View File

@ -10,10 +10,12 @@
#include "bus.h" #include "bus.h"
#include "cpu.h" #include "cpu.h"
#include "disk.h"
#include "framebuffer.h" #include "framebuffer.h"
#include "mouse.h" #include "mouse.h"
extern fox32_vm_t vm; extern fox32_vm_t vm;
extern disk_controller_t disk_controller;
extern mouse_t mouse; extern mouse_t mouse;
int bus_io_read(void *user, uint32_t *value, uint32_t port) { int bus_io_read(void *user, uint32_t *value, uint32_t port) {
@ -71,6 +73,26 @@ int bus_io_read(void *user, uint32_t *value, uint32_t port) {
break; break;
}; };
case 0x80001000 ... 0x80002003: { // disk controller port
size_t id = port & 0xFF;
uint8_t operation = (port & 0x0000F000) >> 8;
switch (operation) {
case 0x10: {
// current insert state of specified disk id
// size will be zero if disk isn't inserted
*value = get_disk_size(id);
break;
};
case 0x20: {
// current buffer pointer
*value = disk_controller.buffer_pointer;
break;
};
}
break;
};
} }
return 0; return 0;
@ -140,6 +162,39 @@ int bus_io_write(void *user, uint32_t value, uint32_t port) {
break; break;
}; };
case 0x80001000 ... 0x80005003: { // disk controller port
size_t id = port & 0xFF;
uint8_t operation = (port & 0x0000F000) >> 8;
switch (operation) {
case 0x10: {
// TODO: ask the user to insert a disk
break;
};
case 0x20: {
// set the buffer pointer
disk_controller.buffer_pointer = value;
break;
};
case 0x30: {
// read specified disk sector into memory
set_disk_sector(id, value);
read_disk_into_memory(id);
break;
};
case 0x40: {
// TODO: write specified disk sector from memory
break;
};
case 0x50: {
// remove specified disk
remove_disk(id);
break;
};
}
break;
};
} }
return 0; return 0;

54
src/disk.c Normal file
View File

@ -0,0 +1,54 @@
#include <SDL2/SDL.h>
#include <getopt.h>
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cpu.h"
#include "disk.h"
disk_controller_t disk_controller;
extern fox32_vm_t vm;
void new_disk(const char *filename, size_t id) {
if (id > 3) { puts("attempting to access disk with ID > 3\n"); return; }
printf("mounting %s as disk ID %d\n", filename, (int) id);
disk_controller.disks[id].file = fopen(filename, "r+b");
fseek(disk_controller.disks[id].file, 0, SEEK_END);
disk_controller.disks[id].size = ftell(disk_controller.disks[id].file);
rewind(disk_controller.disks[id].file);
}
void insert_disk(disk_t disk, size_t id) {
if (id > 3) { puts("attempting to access disk with ID > 3\n"); return; }
if (disk_controller.disks[id].size > 0) remove_disk(id);
printf("mounting disk ID %d\n", (int) id);
disk_controller.disks[id] = disk;
}
void remove_disk(size_t id) {
if (id > 3) { puts("attempting to access disk with ID > 3\n"); return; }
printf("unmounting disk ID %d\n", (int) id);
fclose(disk_controller.disks[id].file);
disk_controller.disks[id].size = 0;
}
uint64_t get_disk_size(size_t id) {
if (id > 3) { puts("attempting to access disk with ID > 3\n"); return 0; }
return disk_controller.disks[id].size;
}
void set_disk_sector(size_t id, uint64_t sector) {
if (id > 3) { puts("attempting to access disk with ID > 3\n"); return; }
fseek(disk_controller.disks[id].file, sector * 512, 0);
}
size_t read_disk_into_memory(size_t id) {
if (id > 3) { puts("attempting to access disk with ID > 3\n"); return 0; }
return fread(&vm.memory_ram[disk_controller.buffer_pointer], 1, 512, disk_controller.disks[id].file);
}

18
src/disk.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
typedef struct {
FILE *file;
uint64_t size;
} disk_t;
typedef struct {
disk_t disks[4];
size_t buffer_pointer;
} disk_controller_t;
void new_disk(const char *filename, size_t id);
void insert_disk(disk_t disk, size_t id);
void remove_disk(size_t id);
uint64_t get_disk_size(size_t id);
void set_disk_sector(size_t id, uint64_t sector);
size_t read_disk_into_memory(size_t id);

View File

@ -9,6 +9,7 @@
#include "bus.h" #include "bus.h"
#include "cpu.h" #include "cpu.h"
#include "disk.h"
#include "framebuffer.h" #include "framebuffer.h"
#include "mouse.h" #include "mouse.h"
#include "screen.h" #include "screen.h"
@ -21,12 +22,14 @@
fox32_vm_t vm; fox32_vm_t vm;
extern disk_controller_t disk_controller;
uint32_t tick_start; uint32_t tick_start;
uint32_t tick_end; uint32_t tick_end;
int ticks = 0; int ticks = 0;
bool done = false; bool done = false;
void MainLoop(void); void main_loop(void);
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (SDL_Init(SDL_INIT_VIDEO) != 0) { if (SDL_Init(SDL_INIT_VIDEO) != 0) {
@ -42,6 +45,12 @@ int main(int argc, char *argv[]) {
memcpy(vm.memory_rom, fox32rom, sizeof(fox32rom)); memcpy(vm.memory_rom, fox32rom, sizeof(fox32rom));
if (argc > 1) {
for (int i = 0; i + 1 < argc; i++) {
new_disk(argv[i + 1], i);
}
}
ScreenCreate( ScreenCreate(
FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
draw_framebuffer, draw_framebuffer,
@ -59,7 +68,7 @@ int main(int argc, char *argv[]) {
tick_end = SDL_GetTicks(); tick_end = SDL_GetTicks();
while (!done) { while (!done) {
MainLoop(); main_loop();
tick_end = SDL_GetTicks(); tick_end = SDL_GetTicks();
int delay = 1000/TPS - (tick_end - tick_start); int delay = 1000/TPS - (tick_end - tick_start);
@ -73,7 +82,7 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
void MainLoop(void) { void main_loop(void) {
int dt = SDL_GetTicks() - tick_start; int dt = SDL_GetTicks() - tick_start;
tick_start = SDL_GetTicks(); tick_start = SDL_GetTicks();
if (!dt) if (!dt)