add msbasic

This commit is contained in:
Kilian committed 2026-09-27 00:34:42 +02:00
1 parent d37d434228
commit c5a028c8c6
104 files changed
+25598 -13802

No files matched your search

+1960 -1960
View File
File diff suppressed because it is too large. Load diff
+16 -13
View File
@@ -1,14 +1,17 @@
#include "io.h"
#include <stdio.h>
int putChar(uint8_t c) {
int _c = putchar(c);
fflush(stdout);
return _c;
}
int getChar(void) {
clearerr(stdin);
return getchar();
#include "io.h"
#include <stdio.h>
int putChar(uint8_t c) {
int _c = putchar(c);
fflush(stdout);
return _c;
}
int getChar(void) {
clearerr(stdin);
int c = getchar();
return c;
}
+89 -87
View File
@@ -1,88 +1,90 @@
#include "cpu.h"
#include "ram.h"
#include "rom.h"
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#define MACHINE_SPEED_HZ 1e6 // 1 MHz;
static struct termios orig_termios;
static struct timespec sleepTime;
void restore_terminal(void) { tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios); }
void set_nonblocking_input(void) {
struct termios raw;
tcgetattr(STDIN_FILENO, &orig_termios);
atexit(restore_terminal);
raw = orig_termios;
raw.c_lflag &= ~(ICANON | ECHO); // disable line buffering and echo
raw.c_cc[VMIN] = 0; // don't block waiting for input
raw.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSANOW, &raw);
// make stdin reads non-blocking too
int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
}
int main(void) {
uint8_t *ram = NULL;
CPU cpu;
set_nonblocking_input();
initRom(rom);
if (createRAM(&ram) != 0) {
printf("Could not create RAM\n");
return 1;
}
/* DEBUG */
//FILE *fp = fopen("/Users/Kili2/Documents/Projekte/6502pc/6502_65C02_functional_tests/6502_functional_test.bin", "rb");
//FILE *fp = fopen("/Users/Kili2/Documents/Projekte/6502pc/6502_65C02_functional_tests/6502_decimal_test.bin", "rb");
FILE *fp = fopen("/mnt/c/Users/llego/source/repos/6502PC/6502_65C02_functional_tests/6502_functional_test.bin", "rb");
//FILE *fp = fopen("/mnt/c/Users/llego/source/repos/6502PC/6502_65C02_functional_tests/6502_decimal_test.bin", "rb");
if (!fp) {
perror("fopen");
return 1;
}
fread(ram, 1, RAM_SIZE, fp);
if (ferror(fp)) {
perror("fread");
fclose(fp);
return 1;
}
fclose(fp);
/* DEBUG END*/
initCPU(&cpu);
resetCPU(&cpu, rom);
while (1) {
uint8_t sleep = runCycle(&cpu, ram, rom);
if (sleep == 1) {
printf("opcode missing: 0x%X\n", ram[cpu.ProgrammeCounter - 1]);
return 1;
}
sleepTime.tv_sec = 0;
sleepTime.tv_nsec = sleep * (1000 / MACHINE_SPEED_HZ);
nanosleep(&sleepTime, NULL);
}
destroyRAM(ram);
return 0;
#include "cpu.h"
#include "ram.h"
#include "rom.h"
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#define MACHINE_SPEED_HZ 1e6 // 1 MHz;
static struct termios orig_termios;
static struct timespec sleepTime;
void restore_terminal(void) { tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios); }
void set_nonblocking_input(void) {
struct termios raw;
tcgetattr(STDIN_FILENO, &orig_termios);
atexit(restore_terminal);
raw = orig_termios;
raw.c_lflag &= ~(ICANON | ECHO); // disable line buffering and echo
raw.c_cc[VMIN] = 0; // don't block waiting for input
raw.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSANOW, &raw);
// make stdin reads non-blocking too
int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
}
int main(void) {
uint8_t *ram = NULL;
CPU cpu;
set_nonblocking_input();
initRom(rom);
if (createRAM(&ram) != 0) {
printf("Could not create RAM\n");
return 1;
}
/* DEBUG */
//FILE *fp = fopen("/Users/Kili2/Documents/Projekte/6502pc/6502_65C02_functional_tests/6502_functional_test.bin", "rb");
//FILE *fp = fopen("/Users/Kili2/Documents/Projekte/6502pc/6502_65C02_functional_tests/6502_decimal_test.bin", "rb");
//FILE *fp = fopen("/mnt/c/Users/llego/source/repos/6502PC/6502_65C02_functional_tests/6502_functional_test.bin", "rb");
//FILE *fp = fopen("/mnt/c/Users/llego/source/repos/6502PC/6502_65C02_functional_tests/6502_decimal_test.bin", "rb");
/*
if (!fp) {
perror("fopen");
return 1;
}
fread(ram, 1, RAM_SIZE, fp);
if (ferror(fp)) {
perror("fread");
fclose(fp);
return 1;
}
fclose(fp);
*/
/* DEBUG END*/
initCPU(&cpu);
resetCPU(&cpu, rom);
while (1) {
uint8_t sleep = runCycle(&cpu, ram, rom);
if (sleep == 1) {
printf("opcode missing: 0x%X\n", ram[cpu.ProgrammeCounter - 1]);
return 1;
}
sleepTime.tv_sec = 0;
sleepTime.tv_nsec = sleep * (1000 / MACHINE_SPEED_HZ);
nanosleep(&sleepTime, NULL);
}
destroyRAM(ram);
return 0;
}
+52 -52
View File
@@ -1,53 +1,53 @@
#include "memoryMap.h"
uint8_t readMemory(uint16_t address, uint8_t *ram, uint8_t *rom) {
if ((address < RAM_SIZE && address < IO_BASE) || address >= ROM_BASE) {
if (address >= ROM_BASE && ram[IO_BASE + ROM_BANKED_OUT] == 0) {
return rom[address - ROM_BASE];
}
return ram[address];
} else {
uint16_t _address = address - IO_BASE;
switch (_address) {
case KEYBOARD_ADDRESS: {
return getChar();
}
case ROM_BANKED_OUT: {
return ram[IO_BASE + ROM_BANKED_OUT];
}
default:
break;
}
return 0;
}
}
void writeMemory(uint16_t address, uint8_t value, uint8_t *ram) {
if ((address < RAM_SIZE && address < IO_BASE) || address >= ROM_BASE) {
if (address < ROM_BASE && ram[IO_BASE + ROM_BANKED_OUT] != 0) {
ram[address] = value;
}
} else {
uint16_t _address = address - IO_BASE;
switch (_address) {
case SCREEN_ADDRESS: {
putChar(value);
break;
}
case ROM_BANKED_OUT: {
ram[IO_BASE + ROM_BANKED_OUT] = value;
break;
}
default:
break;
}
}
}
uint8_t readStack(uint8_t address, uint8_t *ram) { return ram[0x100 + address]; }
#include "memoryMap.h"
uint8_t readMemory(uint16_t address, uint8_t *ram, uint8_t *rom) {
if ((address < RAM_SIZE && address < IO_BASE) || address >= ROM_BASE) {
if (address >= ROM_BASE && ram[IO_BASE + ROM_BANKED_OUT] == 0) {
return rom[address - ROM_BASE];
}
return ram[address];
} else {
uint16_t _address = address - IO_BASE;
switch (_address) {
case KEYBOARD_ADDRESS: {
return getChar();
}
case ROM_BANKED_OUT: {
return ram[IO_BASE + ROM_BANKED_OUT];
}
default:
break;
}
return 0;
}
}
void writeMemory(uint16_t address, uint8_t value, uint8_t *ram) {
if ((address < RAM_SIZE && address < IO_BASE) || address >= ROM_BASE) {
if (address < ROM_BASE && ram[IO_BASE + ROM_BANKED_OUT] != 0) {
ram[address] = value;
}
} else {
uint16_t _address = address - IO_BASE;
switch (_address) {
case SCREEN_ADDRESS: {
putChar(value);
break;
}
case ROM_BANKED_OUT: {
ram[IO_BASE + ROM_BANKED_OUT] = value;
break;
}
default:
break;
}
}
}
uint8_t readStack(uint8_t address, uint8_t *ram) { return ram[0x100 + address]; }
void writeStack(uint8_t address, uint8_t value, uint8_t *ram) { ram[0x100 + address] = value; }
+19 -19
View File
@@ -1,20 +1,20 @@
#include "ram.h"
#include "io.h"
#include <stdlib.h>
int createRAM(uint8_t **ram) {
*ram = (uint8_t *)malloc(RAM_SIZE);
if (*ram == NULL) return -1;
// Zero IO
for (size_t i = IO_BASE; i < IO_SIZE; i++) {
ram[i] = 0;
}
return 0;
}
#include "ram.h"
#include "io.h"
#include <stdlib.h>
int createRAM(uint8_t **ram) {
*ram = (uint8_t *)malloc(RAM_SIZE);
if (*ram == NULL) return -1;
// Zero IO
for (size_t i = IO_BASE; i < IO_SIZE; i++) {
ram[i] = 0;
}
return 0;
}
void destroyRAM(uint8_t *ram) { free(ram); }
+28 -10
View File
@@ -1,11 +1,29 @@
#include "rom.h"
#include "io.h"
uint8_t rom[ROM_SIZE] = {0};
void initRom(uint8_t *rom) {
/* Reset Vector */
rom[0xFFFC - ROM_BASE] = 0x00; // Lower byte base of ROM
rom[0xFFFD - ROM_BASE] = 0x04; // Upper byte of base of ROM
#include "rom.h"
#include "io.h"
#include <stdio.h>
uint8_t rom[ROM_SIZE] = {0};
void initRom(uint8_t *rom) {
FILE *fp = fopen("/mnt/c/Users/llego/source/repos/6502PC/msbasic/tmp/kilian.bin", "rb");
if (!fp) {
perror("fopen");
return;
}
fread(rom, 1, ROM_SIZE, fp);
if (ferror(fp)) {
perror("fread");
fclose(fp);
return;
}
fclose(fp);
/* Reset Vector, BASIC at DF02 */
//rom[0xFFFC - ROM_BASE] = 0x02; // Lower byte base of ROM
//rom[0xFFFD - ROM_BASE] = 0xDF; // Upper byte of base of ROM
}