65C02 opcodes. The cpu core passes nearly all the tests (fuck you decimal mode). Minor fixes here and there. Lo-res fixes and stuff.

This commit is contained in:
LemonBoy 2014-04-27 23:00:11 +02:00
parent 8e45768c29
commit d37d6f0bcf
10 changed files with 523 additions and 258 deletions

View File

@ -6,5 +6,14 @@ void cpu_reset ();
void cpu_nmi (); void cpu_nmi ();
extern u32 cpu_regs[6]; extern u32 cpu_regs[6];
enum {
RF = 0,
RY,
RX,
RA,
RSP,
RPC,
};
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,6 @@ void irq_vblank ()
if (vblanks++ == 60) { if (vblanks++ == 60) {
consoleClear(); consoleClear();
iprintf("FPS %i\n", frames_done); iprintf("FPS %i\n", frames_done);
// iprintf("keybd_latch : %02x\n", keybd_latch);
frames_done = 0; frames_done = 0;
vblanks = 0; vblanks = 0;
} }
@ -27,6 +26,7 @@ int valid_rom_crc (const u16 crc)
const u16 known_crcs[] = { const u16 known_crcs[] = {
0xAC8F, // 12288 BASIC.ROM 0xAC8F, // 12288 BASIC.ROM
0x3F44, // 12288 apple.rom 0x3F44, // 12288 apple.rom
0x9CB5, // 12288 A2ROM.BIN
}; };
int i; int i;
@ -42,14 +42,15 @@ void emu_init ()
u16 crc; u16 crc;
int valid_crc; int valid_crc;
keyboardShow(); keysSetRepeat(30, 10);
/*keyboardShow();*/
// Set some sane defaults // Set some sane defaults
emu_vsync = 1; emu_vsync = 0;
// Setup the video hardware // Setup the video hardware
video_init(); video_init();
#if 1
// Load the appropriate bios // Load the appropriate bios
if (load_bin("BASIC.ROM", 0xD000, 0x3000, &crc)) { if (load_bin("BASIC.ROM", 0xD000, 0x3000, &crc)) {
valid_crc = valid_rom_crc(crc); valid_crc = valid_rom_crc(crc);
@ -64,6 +65,16 @@ void emu_init ()
// Load the disk rom in place // Load the disk rom in place
load_buf(disk_rom, 0xc600, 0x100); load_buf(disk_rom, 0xc600, 0x100);
#else
if (load_bin("6502_functional_test.bin", 0x0, -1, NULL) > 0) {
const u16 reset_patch = 0x0400;
iprintf("Test rom loaded\n");
iprintf("PC : %04x\n", mainram[0xFFFD]<<8|mainram[0xFFFC]);
iprintf("Routing the reset vector to %04x\n", reset_patch);
mainram[0xFFFC] = reset_patch&0xFF;
mainram[0xFFFD] = (reset_patch>>8)&0xFF;
}
#endif
basename = NULL; basename = NULL;

View File

@ -23,11 +23,13 @@ void update_input ()
int kbd_key; int kbd_key;
scanKeys(); scanKeys();
keys = keysHeld()&0xfff; keys = (keysDownRepeat()|keysDown())&0xfff;
// Send keyboard scancodes when a key is pressed // Send keyboard scancodes when a key is pressed
if (emu_input == INPUT_KBD && keys) { if (emu_input == INPUT_KBD && keys) {
keybd_latch = 0x80 ^ key_map[__builtin_ctz(keys)]; int bit_set = __builtin_ffs(keys);
if (bit_set)
keybd_latch = 0x80 ^ key_map[bit_set-1];
} }
if (emu_input == INPUT_JSTK) { if (emu_input == INPUT_JSTK) {

View File

@ -13,20 +13,21 @@ int main(int argc, char **argv)
keyboardDemoInit(); keyboardDemoInit();
fatInitDefault(); fatInitDefault();
/*nitroFSInit(NULL);*/ nitroFSInit(NULL);
soundEnable(); soundEnable();
iprintf("-- grape\n"); iprintf("-- grape\n");
emu_init(); emu_init();
if (argc != 2) { if (argc != 2) {
/*load_disk("Airheart (1986)(Broderbund)[cr].dsk");*/
// Slow loading // Slow loading
/*load_disk("PACMAN.DSK");*/ /*load_disk("PACMAN.DSK");*/
/*load_disk("Karateka (1984)(Broderbund).dsk");*/ /*load_disk("Karateka (1984)(Broderbund).dsk");*/
// Awesome! // Awesome!
/*load_disk("lode.dsk");*/ load_disk("lode.dsk");
// AppleII+ // AppleII+
/*load_disk("Prince of Persia (1989)(Broderbund)(Disk 1 of 3)[cr].dsk");*/ /*load_disk("Prince of Persia (1989)(Broderbund)(Disk 1 of 3)[cr].dsk");*/
// Gfx heavy // Gfx heavy
@ -36,13 +37,14 @@ int main(int argc, char **argv)
/*load_disk("Round About (1983)(Datamost).dsk");*/ /*load_disk("Round About (1983)(Datamost).dsk");*/
/*load_disk("Bug Attack (1981)(Cavalier Computer).dsk");*/ /*load_disk("Bug Attack (1981)(Cavalier Computer).dsk");*/
// Scroller // Scroller
load_disk("TetrisII.DSK"); /*load_disk("TetrisII.DSK");*/
// Mixed mode // Mixed mode
/*load_disk("tetris48k.nib");*/ /*load_disk("tetris48k.nib");*/
// Lowres // Lowres
/*load_disk("Fracas (1980)(Quality Software).dsk");*/ /*load_disk("Fracas (1980)(Quality Software).dsk");*/
/*load_disk("Colorix.dsk");*/ /*load_disk("Colorix.dsk");*/
/*load_disk("LoRes Games.DSK");*/ /*load_disk("LoRes Games.DSK");*/
/*load_disk("LoRes Hijinks.DSK");*/
// SP Crash // SP Crash
/*load_disk("Apple II Business Graphics 1.0 (1981).nib");*/ /*load_disk("Apple II Business Graphics 1.0 (1981).nib");*/
} else { } else {

View File

@ -16,8 +16,8 @@ u8 readb (u16 addr);
void writeb (u16 addr, u8 val); void writeb (u16 addr, u8 val);
void mem_reset (void); void mem_reset (void);
int load_bin (char *file, u16 addr, u16 len, u16 *crc); ssize_t load_bin (const char *file, const u32 addr, ssize_t len, u16 *crc);
int load_buf (const u8 *buf, u16 addr, u16 len); ssize_t load_buf (const u8 *buf, const u32 addr, ssize_t len);
#endif #endif

View File

@ -4,36 +4,48 @@
#include "cpu.h" #include "cpu.h"
#include "mem.h" #include "mem.h"
int load_buf (const u8 *buf, u16 addr, u16 len) ssize_t load_buf (const u8 *buf, const u32 addr, const ssize_t len)
{ {
if (addr + len > 0x10000) { if (addr + len > 0x10000) {
iprintf("oob\n"); iprintf("oob\n");
return 0; return -1;
} }
memcpy(mainram + addr, buf, len); memcpy(mainram + addr, buf, len);
return 1; return len;
} }
int load_bin (char *file, u16 addr, u16 len, u16 *crc) ssize_t load_bin (const char *file, const u32 addr, const ssize_t len, u16 *crc)
{ {
FILE *f; FILE *f;
size_t read, bin_len;
if (addr + len > 0x10000) {
iprintf("oob\n");
return 0;
}
f = fopen(file, "rb"); f = fopen(file, "rb");
if (!f) { if (!f) {
iprintf("Can't open %s\n", file); iprintf("Can't open %s\n", file);
return 0; return -1;
} }
fread(mainram + addr, 1, len, f);
if (len < 0) {
fseek(f, 0, SEEK_END);
bin_len = ftell(f);
fseek(f, 0, SEEK_SET);
} else
bin_len = len;
if (addr + bin_len > 0x10000) {
bin_len = 0x4000;
iprintf("oob\n");
fclose(f);
return -1;
}
read = fread(mainram + addr, 1, bin_len, f);
fclose(f); fclose(f);
iprintf("Read %x to %x\n", read, addr);
if (crc) if (crc)
*crc = swiCRC16(0xffff, mainram + addr, len); *crc = swiCRC16(0xffff, mainram + addr, read);
return 1; return read;
} }

View File

@ -75,18 +75,18 @@ void menu_print_page (const page_t *page, int *opts)
if (sel_entry->opts_no) { if (sel_entry->opts_no) {
if (keys&KEY_LEFT && opts[cur] > 0) { if (keys&KEY_LEFT && opts[cur] > 0) {
opts[cur]--; opts[cur]--;
if (sel_entry->cb) sel_entry->cb(opts[cur]); /*if (sel_entry->cb) sel_entry->cb(opts[cur]);*/
} }
if (keys&KEY_RIGHT && opts[cur] < sel_entry->opts_no - 1) { if (keys&KEY_RIGHT && opts[cur] < sel_entry->opts_no - 1) {
opts[cur]++; opts[cur]++;
if (sel_entry->cb) sel_entry->cb(opts[cur]); /*if (sel_entry->cb) sel_entry->cb(opts[cur]);*/
} }
} }
if (keys&KEY_A) { if (keys&KEY_A) {
if (sel_entry->cb) if (sel_entry->cb)
sel_entry->cb(opts[cur]); // TODO : Handle errors if (sel_entry->cb(opts[cur]))
return; return;
} }
// Use keysDown to avoid bouncing // Use keysDown to avoid bouncing
@ -97,4 +97,10 @@ void menu_print_page (const page_t *page, int *opts)
} }
} }
void print_msg (const char *msg)
{
iprintf("\n-- %s\n", msg);
swiDelay(10000000);
}
void pause_menu () { menu_print_page(&paused_pg, (int *)&paused_pg_opt); } void pause_menu () { menu_print_page(&paused_pg, (int *)&paused_pg_opt); }

View File

@ -11,7 +11,7 @@ typedef struct state_hdr_t {
#define STATE_MAGIC (0x47525033) #define STATE_MAGIC (0x47525033)
char *build_path (int slot) char *build_path (const int slot)
{ {
static char tmp[1024]; static char tmp[1024];
if (basename) if (basename)
@ -21,14 +21,18 @@ char *build_path (int slot)
return tmp; return tmp;
} }
int state_save (int slot) int state_save (const int slot)
{ {
FILE *f; FILE *f;
state_hdr_t h; state_hdr_t h;
const char *path;
f = fopen(build_path(slot), "w+"); path = build_path(slot+1);
if (f) f = fopen(path, "wb");
if (!f) {
print_msg("Save failed!");
return 0; return 0;
}
h.magic = STATE_MAGIC; h.magic = STATE_MAGIC;
h.ver = 1; h.ver = 1;
@ -56,22 +60,27 @@ int state_save (int slot)
return 1; return 1;
} }
int state_load (int slot) int state_load (const int slot)
{ {
FILE *f; FILE *f;
state_hdr_t h; state_hdr_t h;
const char *path;
f = fopen(build_path(slot), "w+"); path = build_path(slot+1);
if (f) f = fopen(path, "rb");
if (!f) {
print_msg("Load failed!");
return 0; return 0;
}
h.magic = STATE_MAGIC;
h.ver = 1;
h.flags = 0;
h.resv = 0;
fread(&h, 1, sizeof(state_hdr_t), f); fread(&h, 1, sizeof(state_hdr_t), f);
if (h.magic != STATE_MAGIC) {
fclose(f);
print_msg("Invalid save file!");
return 0;
}
fread(&cpu_regs, 6, 4, f); fread(&cpu_regs, 6, 4, f);
fread(&mainram, 1, sizeof(mainram), f); fread(&mainram, 1, sizeof(mainram), f);
fread(&lcram, 1, sizeof(lcram), f); fread(&lcram, 1, sizeof(lcram), f);

View File

@ -112,11 +112,11 @@ u8 video_io_read (u16 addr)
switch (addr&0xf) { switch (addr&0xf) {
case 0x0: case 0x0:
text_mode = 0; text_mode = 0;
mixed_mode = 0; /*mixed_mode = 0;*/
break; break;
case 0x1: case 0x1:
text_mode = 1; text_mode = 1;
mixed_mode = 0; /*mixed_mode = 0;*/
break; break;
case 0x2: case 0x2:
mixed_mode = 0; mixed_mode = 0;
@ -132,11 +132,9 @@ u8 video_io_read (u16 addr)
break; break;
case 0x6: case 0x6:
hires = 0; hires = 0;
mixed_mode = 0;
break; break;
case 0x7: case 0x7:
hires = 1; hires = 1;
mixed_mode = 0;
break; break;
// Annunciators // Annunciators
case 0x8: case 0x8:
@ -176,12 +174,13 @@ void draw_lores_scr (u16 *map)
*map++ = col_a << 8 | col_a; *map++ = col_a << 8 | col_a;
*map++ = col_a << 8 | col_a; *map++ = col_a << 8 | col_a;
*map++ = col_a << 8 | col_a; *map++ = col_a << 8 | col_a;
*map++ = col_b << 8 | col_a; *map++ = col_a << 8 | col_a;
*map++ = col_b << 8 | col_b;
*map++ = col_b << 8 | col_b; *map++ = col_b << 8 | col_b;
*map++ = col_b << 8 | col_b; *map++ = col_b << 8 | col_b;
*map++ = col_b << 8 | col_b; *map++ = col_b << 8 | col_b;
} }
map += 232/2; map += 192/2;
} }
} }
@ -320,24 +319,25 @@ void video_draw ()
int video_set_scale (int mode) int video_set_scale (int mode)
{ {
int scale_x; int scaleg_x, scalet_x;
int scale_y; int scale_y;
switch (mode) { switch (mode) {
default: default:
case 0: case 0:
scale_x = floatToFixed(1., 8); scaleg_x = scalet_x = floatToFixed(1., 8);
scale_y = floatToFixed(1., 8); scale_y = floatToFixed(1., 8);
break; break;
case 1: case 1:
// 280 / 256 = 1.09 // 280 / 256 = 1.09
scale_x = floatToFixed(1.09, 8); scaleg_x = floatToFixed(1.09, 8);
scalet_x = floatToFixed(1.25, 8);
scale_y = floatToFixed(1., 8); scale_y = floatToFixed(1., 8);
break; break;
} }
bgSetScale(gfx_bg, scale_x, scale_y); bgSetScale(gfx_bg, scaleg_x, scale_y);
bgSetScale(text_bg, scale_x, scale_y); bgSetScale(text_bg, scalet_x, scale_y);
return 1; return 1;
} }