Compare commits
2 Commits
b667561da9
...
ed3ed7bd03
Author | SHA1 | Date | |
---|---|---|---|
ed3ed7bd03 | |||
ec678cb3d0 |
@ -5,3 +5,7 @@ add_executable(pat80-emulator main.c)
|
||||
|
||||
find_package(Z80 REQUIRED)
|
||||
target_link_libraries(pat80-emulator Z80)
|
||||
|
||||
find_package(Curses REQUIRED)
|
||||
include_directories(${CURSES_INCLUDE_DIR})
|
||||
target_link_libraries(pat80-emulator ${CURSES_LIBRARIES})
|
||||
|
@ -1,12 +1,15 @@
|
||||
/**
|
||||
* PAT80 Emulator
|
||||
*
|
||||
* Emulates a PAT80.
|
||||
*/
|
||||
|
||||
#include <Z/constants/pointer.h> /* Z_NULL */
|
||||
#include <Z80.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ncurses.h>
|
||||
|
||||
#define CYCLES_PER_FRAME 69888
|
||||
#define CYCLES_AT_INT 24
|
||||
#define CYCLES_PER_INT 32
|
||||
#define ROM_SIZE 0x8000 /* 32 KiB */
|
||||
#define MEMORY_SIZE 0xFFFF /* 64 KiB */
|
||||
|
||||
@ -20,8 +23,6 @@ typedef struct {
|
||||
zusize cycles;
|
||||
zuint8 memory[65536];
|
||||
Z80 cpu;
|
||||
Device* devices;
|
||||
zusize device_count;
|
||||
} Machine;
|
||||
|
||||
|
||||
@ -45,45 +46,44 @@ static zuint8 machine_cpu_in(Machine *self, zuint16 port) {
|
||||
int decoded = port & bitmask;
|
||||
if (decoded <= 0x1F) {
|
||||
// Port 0 (0x00 to 0x1F): terminal
|
||||
//printf("TERMINAL_READ");
|
||||
//return 'H';
|
||||
return 0x00;
|
||||
// Read char from stin
|
||||
return getch();
|
||||
}
|
||||
if (decoded <= 0x3F) {
|
||||
// Port 1 (0x20 to 0x3F): sound card (sn76489)
|
||||
printf("\nsound_cmd[IN]: Not supported!\n");
|
||||
printw("\nsound_cmd[IN]: Not supported!\n");
|
||||
return 0x00;
|
||||
}
|
||||
if (decoded <= 0x5F) {
|
||||
// Port 2 (0x40 to 0x5F)
|
||||
printf("IO_ERROR_IN: No device at port 2\n");
|
||||
printw("IO_ERROR_IN: No device at port 2\n");
|
||||
return 0x00;
|
||||
}
|
||||
if (decoded <= 0x7F) {
|
||||
// Port 3 (0x60 to 0x7F)
|
||||
printf("IO_ERROR_IN: No device at port 3\n");
|
||||
printw("IO_ERROR_IN: No device at port 3\n");
|
||||
return 0x00;
|
||||
}
|
||||
if (decoded <= 0x9F) {
|
||||
// Port 4 (0x80 to 0x9F)
|
||||
printf("IO_ERROR_IN: No device at port 4\n");
|
||||
printw("IO_ERROR_IN: No device at port 4\n");
|
||||
return 0x00;
|
||||
}
|
||||
if (decoded <= 0x5F) {
|
||||
// Port 5 (0xA0 to 0xBF)
|
||||
printf("IO_ERROR_IN: No device at port 5\n");
|
||||
printw("IO_ERROR_IN: No device at port 5\n");
|
||||
return 0x00;
|
||||
}
|
||||
if (decoded <= 0x5F) {
|
||||
// Port 6 (0xC0 to 0xDF)
|
||||
printf("IO_ERROR_IN: No device at port 6\n");
|
||||
printw("IO_ERROR_IN: No device at port 6\n");
|
||||
return 0x00;
|
||||
}
|
||||
if (decoded <= 0x5F) {
|
||||
// Port 7 (0xE0 to 0xFF)
|
||||
printf("IO_ERROR_IN: No device at port 7\n");
|
||||
printw("IO_ERROR_IN: No device at port 7\n");
|
||||
} else {
|
||||
printf("IO_ERROR_IN: Invalid port address: %#04x\n", port);
|
||||
printw("IO_ERROR_IN: Invalid port address: %#04x\n", port);
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,30 +97,32 @@ static void machine_cpu_out(Machine *self, zuint16 port, zuint8 value) {
|
||||
int decoded = port & bitmask;
|
||||
if (decoded <= 0x1F) {
|
||||
// Port 0 (0x00 to 0x1F): terminal
|
||||
printf("%c", value);
|
||||
attron(A_BOLD);
|
||||
printw("%c", value);
|
||||
attroff(A_BOLD);
|
||||
} else if (decoded <= 0x3F) {
|
||||
// Port 1 (0x20 to 0x3F): sound card (sn76489)
|
||||
printf("\nsound_cmd[%#04x]\n", value);
|
||||
printw("\nsound_cmd[%#04x]\n", value);
|
||||
} else if (decoded <= 0x5F) {
|
||||
// Port 2 (0x40 to 0x5F)
|
||||
printf("IO_ERROR_OUT: No device at port 2\n");
|
||||
printw("IO_ERROR_OUT: No device at port 2\n");
|
||||
} else if (decoded <= 0x7F) {
|
||||
// Port 3 (0x60 to 0x7F)
|
||||
printf("IO_ERROR_OUT: No device at port 3\n");
|
||||
printw("IO_ERROR_OUT: No device at port 3\n");
|
||||
} else if (decoded <= 0x9F) {
|
||||
// Port 4 (0x80 to 0x9F)
|
||||
printf("IO_ERROR_OUT: No device at port 4\n");
|
||||
printw("IO_ERROR_OUT: No device at port 4\n");
|
||||
} else if (decoded <= 0x5F) {
|
||||
// Port 5 (0xA0 to 0xBF)
|
||||
printf("IO_ERROR_OUT: No device at port 5\n");
|
||||
printw("IO_ERROR_OUT: No device at port 5\n");
|
||||
} else if (decoded <= 0x5F) {
|
||||
// Port 6 (0xC0 to 0xDF)
|
||||
printf("IO_ERROR_OUT: No device at port 6\n");
|
||||
printw("IO_ERROR_OUT: No device at port 6\n");
|
||||
} else if (decoded <= 0x5F) {
|
||||
// Port 7 (0xE0 to 0xFF)
|
||||
printf("IO_ERROR_OUT: No device at port 7\n");
|
||||
printw("IO_ERROR_OUT: No device at port 7\n");
|
||||
} else {
|
||||
printf("IO_ERROR_OUT: Invalid port address: %#04x\n", port);
|
||||
printw("IO_ERROR_OUT: Invalid port address: %#04x\n", port);
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,8 +147,6 @@ void machine_initialize(Machine *self) {
|
||||
self->cpu.hook = Z_NULL;
|
||||
self->cpu.illegal = Z_NULL;
|
||||
self->cpu.options = Z80_MODEL_ZILOG_NMOS;
|
||||
|
||||
/* Create and initialize devices... */
|
||||
}
|
||||
|
||||
|
||||
@ -169,47 +169,6 @@ void machine_run(Machine *self) {
|
||||
z80_run(&self->cpu, Z80_MAXIMUM_CYCLES);
|
||||
}
|
||||
|
||||
|
||||
// void machine_run_frame(Machine *self)
|
||||
// {
|
||||
// /* CPU cycles before the INT signal */
|
||||
// self->cycles += z80_execute(&self->cpu, CYCLES_AT_INT - self->cycles);
|
||||
|
||||
// /* CPU cycles during the INT signal */
|
||||
// z80_int(&self->cpu, Z_TRUE);
|
||||
// self->cycles += z80_run(&self->cpu, (CYCLES_AT_INT + CYCLES_PER_INT) - self->cycles);
|
||||
// z80_int(&self->cpu, Z_FALSE);
|
||||
|
||||
// /* CPU cycles after the INT signal */
|
||||
// self->cycles += z80_execute(&self->cpu, CYCLES_PER_FRAME - self->cycles);
|
||||
|
||||
// self->cycles -= CYCLES_PER_FRAME;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
// TEST IMPLEM DEVICE
|
||||
|
||||
zuint8 device_terminal_read(void *context) {
|
||||
return 'H';
|
||||
//return 0;
|
||||
}
|
||||
|
||||
void device_terminal_write(void *context, zuint8 value) {
|
||||
printf("%c", value);
|
||||
}
|
||||
|
||||
zuint8 device_sound_read(void *context) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void device_sound_write(void *context, zuint8 value) {
|
||||
printf("sound[%c]\n", value);
|
||||
}
|
||||
|
||||
// TEST IMPLEM DEVICE
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Parse arguments
|
||||
if (argc < 2) {
|
||||
@ -221,7 +180,7 @@ int main(int argc, char *argv[]) {
|
||||
// Setup virtual Pat80 computer
|
||||
Z80 pat80Cpu = {};
|
||||
Machine pat80 = {
|
||||
/*zusize*/ .cycles = 100000,
|
||||
/*zusize*/ .cycles = 0,
|
||||
/*Z80*/ .cpu = pat80Cpu
|
||||
};
|
||||
|
||||
@ -238,23 +197,18 @@ int main(int argc, char *argv[]) {
|
||||
fread(&pat80.memory,ROM_SIZE,1,romFile); // load rom from file into memory, up >
|
||||
fclose(romFile);
|
||||
|
||||
// Declare system devices
|
||||
Device patoTerminal = {
|
||||
.read = *device_terminal_read,
|
||||
.write = *device_terminal_write,
|
||||
};
|
||||
Device patoSound = {
|
||||
.read = *device_sound_read,
|
||||
.write = *device_sound_write,
|
||||
};
|
||||
|
||||
Device patoDevices[2] = {
|
||||
patoTerminal, // Port 0 (0x00 to 0x1F)
|
||||
patoSound // Port 1 (0x20 to 0x3F)
|
||||
};
|
||||
pat80.devices = patoDevices;
|
||||
pat80.device_count = 2;
|
||||
// Init ncurses
|
||||
initscr(); // Start curses mode
|
||||
raw(); // Line buffering disabled (get character without waiting for ENTER key)
|
||||
keypad(stdscr, TRUE); // We get F1, F2 etc..
|
||||
noecho(); // Don't echo() while we do getch
|
||||
scrollok(stdscr, TRUE); // Allow scrolling when reached end of window
|
||||
|
||||
// Start emulated computer
|
||||
machine_reset(&pat80);
|
||||
machine_run(&pat80);
|
||||
|
||||
// Stop ncurses
|
||||
endwin(); /* End curses mode */
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user