cbm3001-memtest/emu6502.c

85 lines
2.7 KiB
C

#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <sys/mman.h>
#define RAMSIZE 0x1000
extern uint32_t instructions;
extern void reset6502(void);
extern void step6502(void);
uint8_t *ram, *screen, *f000;
uint8_t read6502(uint16_t address) {
if (address == _END) {
printf("DONE\n");
exit(0);
}
uint8_t value = 0x00;
if (address < RAMSIZE) {
if (address >= RAMSIZE-16) {
// emulate memory error in uppermost page
value = ram[address] & 0xf7;
} else if (address >= 0x0100 && address <= 0x01ff) {
// simulate broken LSB in stack page
value = ram[address & 0xfffe];
} else {
value = ram[address];
}
printf("%08x: READ %04x -> %02x\n", instructions, address, value);
} else if (address >= 0x8000 && address <= 0x8fff) {
// screen buffer is mirrored 4 times, discard upper 2 bytes
value = screen[address & 0x03ff];
printf("%08x: READ %04x -> %02x\n", instructions, address, value);
} else if (address >= 0xf000) {
value = f000[address-0xf000];
printf("%08x: READ %04x -> %02x\n", instructions, address, value);
} else {
printf("%08x: READ %04x -> not implemented\n", instructions, address);
}
return value;
}
void write6502(uint16_t address, uint8_t value) {
if (address < RAMSIZE) {
printf("%08x: WRITE %04x <- %02x\n", instructions, address, value);
// simulate broken LSB in stack page
if (address >= 0x100 && address <= 0x1ff) {
ram[address & 0xfffe] = value;
} else {
ram[address] = value;
}
} else if (address >= 0x8000 && address <= 0x8fff) {
printf("%08x: WRITE %04x <- %02x, SCREEN(%d,%d)\n", instructions, address, value, (address&0x03ff)%40, (address&0x03ff)/40);
screen[address & 0x03ff] = value;
} else {
printf("%08x: WRITE %04x <- %02x; READONLY\n", instructions, address, value);
}
}
int main() {
ram = (uint8_t*) malloc(RAMSIZE);
screen = (uint8_t*) malloc(0x400);
memset(screen, 'X', 0x400);
int ffd = open("memtest-f000.901465+ascii.bin", O_RDONLY);
f000 = mmap(0, 0x1000, PROT_READ, MAP_PRIVATE, ffd, 0);
reset6502();
while (1) {
usleep(1);
step6502();
printf("pass: %02x, address: %02x%02x\n", ram[4], ram[1], ram[2]);
printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
for (uint8_t row = 0; row < 25; ++row) {
printf("┃%.40s┃\n", screen + 40*row);
}
printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
}
}