diff --git a/main.c b/main.c index 9ccafd9..5f357a3 100644 --- a/main.c +++ b/main.c @@ -21,15 +21,15 @@ #include #include #include -#include "source/log.h" -#include "source/rom.h" -#include "source/nec/nec.h" -#include "source/memory.h" -#include "source/gpu.h" -#include "source/io.h" -#include "source/ws.h" -#include "source/emulate.h" -#include "source/audio.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include //////////////////////////////////////////////////////////////////////////////// // @@ -182,7 +182,6 @@ int main(int argc, char *argv[]) if (ws_init(ws_rom_path)) { ws_reset(); - ws_emulate(); } diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 0af9039..b0085f3 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1,5 +1,5 @@ set(SOURCES audio.c emulate.c gpu.c io.c log.c memory.c rom.c ws.c) -set(HEADERS audio.h emulate.h gpu.h io.h log.h memory.h rom.h ws.h) +set(HEADERS includes/audio.h includes/emulate.h includes/gpu.h includes/io.h includes/log.h includes/memory.h includes/rom.h includes/ws.h) option(FAKE_DISPLAY "Disable OpenGL and fake displaying" OFF) @@ -11,6 +11,6 @@ endif() target_link_libraries(wswan nec_v30 glfw ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY}) -target_include_directories(wswan PUBLIC . nec/) +target_include_directories(wswan PUBLIC includes/) add_subdirectory(nec) \ No newline at end of file diff --git a/source/audio.c b/source/audio.c index b52860c..86d5af7 100644 --- a/source/audio.c +++ b/source/audio.c @@ -28,12 +28,12 @@ #include #include #include -#include "log.h" -#include "rom.h" -#include "./nec/nec.h" -#include "memory.h" -#include "io.h" -#include "audio.h" +#include +#include +#include "nec.h" +#include +#include +#include #define SNDP ws_ioRam[0x80] #define SNDV ws_ioRam[0x88] diff --git a/source/emulate.c b/source/emulate.c index 2d87f25..845ad25 100644 --- a/source/emulate.c +++ b/source/emulate.c @@ -38,15 +38,15 @@ #endif #endif /* PRETENT_DISPLAY */ -#include "log.h" -#include "io.h" -#include "ws.h" -#include "rom.h" -#include "./nec/nec.h" -#include "./nec/necintrf.h" -#include "gpu.h" -#include "audio.h" -#include "memory.h" +#include +#include +#include +#include +#include "nec.h" +#include "necintrf.h" +#include +#include +#include char app_window_title[256]; int app_terminate = 0; @@ -479,7 +479,7 @@ void ws_emulate(void) /* What is this mess? Frameskip? */ for (i = 0 ; i < nCount - 1 ; i++) { - while (!ws_executeLine(backBuffer, 0)) + while (!ws_executeLine(backBuffer, 1)) { } } diff --git a/source/gpu.c b/source/gpu.c index 4094363..3e27f03 100644 --- a/source/gpu.c +++ b/source/gpu.c @@ -27,12 +27,13 @@ #include #include #include -#include "log.h" -#include "rom.h" -#include "./nec/nec.h" -#include "io.h" -#include "gpu.h" -#include "ws.h" +#include +#include +#include "nec.h" +#include +#include +#include +#include //////////////////////////////////////////////////////////////////////////////// // @@ -187,7 +188,6 @@ void ws_gpu_changeVideoMode(uint8_t value) (value & 0x80)?'Y':'N', (value & 0x40)?'4':'2', (value & 0x20)?"Packed":"Planar"); - } //////////////////////////////////////////////////////////////////////////////// diff --git a/source/audio.h b/source/includes/audio.h similarity index 100% rename from source/audio.h rename to source/includes/audio.h diff --git a/source/includes/device.h b/source/includes/device.h new file mode 100644 index 0000000..b60f3da --- /dev/null +++ b/source/includes/device.h @@ -0,0 +1,24 @@ +/* + * NewOswan + * device.h: + * + * Created by Manoël Trapier on 19/12/2021. + * Copyright (c) 2014-2021 986-Studio. All rights reserved. + * + */ + +#ifndef NEWOSWAN_DEVICE_H +#define NEWOSWAN_DEVICE_H + +typedef void (*device_init)(void); +typedef void (*device_reset)(void); +typedef void (*device_free)(void); + +typedef struct device_t +{ + device_init *init; + device_reset *reset; + device_free *free; +} device_t; + +#endif /* NEWOSWAN_DEVICE_H */ diff --git a/source/emulate.h b/source/includes/emulate.h similarity index 100% rename from source/emulate.h rename to source/includes/emulate.h diff --git a/source/gpu.h b/source/includes/gpu.h similarity index 93% rename from source/gpu.h rename to source/includes/gpu.h index b1e77ab..27bf745 100644 --- a/source/gpu.h +++ b/source/includes/gpu.h @@ -11,6 +11,12 @@ #include +struct ws_gpu_t +{ + uint8_t scanline; + uint32_t cyclecount; +}; + extern uint8_t ws_gpu_scanline; extern uint8_t ws_gpu_operatingInColor; extern uint8_t ws_videoMode; diff --git a/source/io.h b/source/includes/io.h similarity index 72% rename from source/io.h rename to source/includes/io.h index 505e678..1c08463 100644 --- a/source/io.h +++ b/source/includes/io.h @@ -39,7 +39,12 @@ void io_flipControls(void); void io_done(void); uint8_t io_readport(uint8_t port); -void io_writeport(uint32_t port, uint8_t value); +void io_writeport(uint8_t port, uint8_t value); + +typedef uint8_t (*io_read)(void *pdata, uint8_t port); +typedef void (*io_write)(void *pdata, uint8_t port, uint8_t value); + +void register_io_hook(uint8_t port, io_read *readHook, io_write writeHook, void *pdata); +void register_io_hook_array(uint8_t *portList, uint8_t listLen, io_read *readHook, io_write writeHook, void *pdata); #endif - diff --git a/source/log.h b/source/includes/log.h similarity index 99% rename from source/log.h rename to source/includes/log.h index 6b67900..23cfa57 100644 --- a/source/log.h +++ b/source/includes/log.h @@ -13,7 +13,7 @@ extern "C" { #endif -#define ALLOW_COLORS +//#define ALLOW_COLORS #ifdef ALLOW_COLORS #define __C(c) "\x1B[" c "m" diff --git a/source/memory.h b/source/includes/memory.h similarity index 92% rename from source/memory.h rename to source/includes/memory.h index c346beb..e7fb0e2 100644 --- a/source/memory.h +++ b/source/includes/memory.h @@ -57,6 +57,16 @@ void set_irom_overlay(); uint8_t *getRom(uint32_t *size); uint8_t *getSram(uint32_t *size); + +void mem_dump_info(); + +typedef enum { + IRAM_FULL_ACCESS, + IRAM_LIMITED_ACCESS, +} iram_access_t; + +void set_iram_access(iram_access_t mode); + #endif #define mem_readop mem_readmem20 diff --git a/source/nec/nec.h b/source/includes/nec.h similarity index 100% rename from source/nec/nec.h rename to source/includes/nec.h diff --git a/source/nec/nec_debugger.h b/source/includes/nec_debugger.h similarity index 100% rename from source/nec/nec_debugger.h rename to source/includes/nec_debugger.h diff --git a/source/nec/necintrf.h b/source/includes/necintrf.h similarity index 100% rename from source/nec/necintrf.h rename to source/includes/necintrf.h diff --git a/source/rom.h b/source/includes/rom.h similarity index 100% rename from source/rom.h rename to source/includes/rom.h diff --git a/source/ws.h b/source/includes/ws.h similarity index 100% rename from source/ws.h rename to source/includes/ws.h diff --git a/source/io.c b/source/io.c index f9adbbc..3440989 100644 --- a/source/io.c +++ b/source/io.c @@ -18,60 +18,35 @@ #include #include #include -#include #include -#include /* UNIX standard function definitions */ -#include /* Error number definitions */ -#include /* POSIX terminal control definitions */ -#include - -#include "log.h" -#include "rom.h" -#include "./nec/nec.h" -#include "./nec/necintrf.h" -#include "gpu.h" -#include "audio.h" -#include "memory.h" -#include "ws.h" #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + //#define IO_DUMP //define EEPROM_DEBUG -extern uint8_t *externalEeprom; +typedef struct ioregistry_t +{ + io_read read; /***< Read function for a specific IO port */ + io_write write; /***< Write function for a specific IO port */ + void *private; /***< Private data for the peripheral if needed. */ +} ioregistry_t; +ioregistry_t io_registry[0x100]; + extern uint32_t romAddressMask; -extern uint16_t *internalEeprom; extern nec_Regs I; extern uint64_t nec_monotonicCycles; extern uint32_t sramSize; -enum -{ - EEPROM_SUBCOMMAND = 0, /* 00 00 */ - EEPROM_WRITE, /* 01 xx */ - EEPROM_READ, /* 10 xx */ - EEPROM_ERASE, /* 11 xx */ - EEPROM_WRITEDISABLE, /* 00 00 */ - EEPROM_WRITEALL, /* 00 01 */ - EEPROM_ERASEALL, /* 00 10 */ - EEPROM_WRITEENABLE /* 00 11 */ -}; - -char *eii_CommandName[] = { - "SUB", "WRI", "RED", "ERA", "WRD", "WRA", "ERL", "WRE", -}; - -uint8_t iee_WriteEnable = false; -uint16_t iee_SelAddress = 0; -uint16_t iee_Databuffer = 0; -uint8_t iee_Mode = EEPROM_READ; - -uint8_t cee_WriteEnable = true; -uint16_t cee_SelAddress = 0; -uint16_t cee_Databuffer = 0; -uint8_t cee_Mode = EEPROM_READ; - - uint8_t *ws_ioRam = NULL; uint8_t ws_key_start; @@ -87,8 +62,6 @@ uint8_t ws_key_button_a; uint8_t ws_key_button_b; uint8_t ws_key_flipped; -int rtcDataRegisterReadCount = 0; - FILE *ioLogFp = NULL; //////////////////////////////////////////////////////////////////////////////// @@ -131,8 +104,6 @@ void io_reset(void) ws_ioRam[0xC1] = 0xFF; ws_ioRam[0xC2] = 0xFF; ws_ioRam[0xC3] = 0xFF; - - rtcDataRegisterReadCount = 0; } //////////////////////////////////////////////////////////////////////////////// @@ -200,146 +171,6 @@ void io_done(void) #endif } -/* Serial port */ -#define BDR_9600 (0) -#define BDR_38400 (1) -#define SERIAL_PORT "/dev/tty.USA19H141P1.1" -int serialfd = -1; -int serial_have_data = 0; -unsigned char serial_data = 0; -int serial_speed = BDR_9600; - -void open_serial() -{ - if (serialfd < 0) - { - serialfd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY); - - //set_baudrate(serial_speed); - serial_have_data = 0; - } -} - -void set_baudrate(int speed) -{ - struct termios options; - - if (serialfd < 0) - { - return; - } - - tcgetattr(serialfd, &options); - - options.c_cflag &= ~PARENB; - options.c_cflag &= ~CSTOPB; - options.c_cflag &= ~CSIZE; - options.c_cflag |= CS8; - - if (speed == BDR_9600) - { - cfsetispeed(&options, B9600); - } - else - { - cfsetospeed(&options, B38400); - } - -#if 0 - options.c_cflag &= ~CNEW_RTSCTS; -#else - options.c_cflag &= ~CRTSCTS; -#endif - options.c_cflag |= (CLOCAL | CREAD); - - options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); - - options.c_oflag &= ~OPOST; - - tcsetattr(serialfd, TCSANOW, &options); - - /* Make sure read is not blocking */ - fcntl(serialfd, F_SETFL, FNDELAY); -} - -void close_serial() -{ - close(serialfd); - serialfd = -1; -} - -void check_serial_data() -{ - unsigned char buf[10]; - int f; - - if (serialfd < 0) - { - return; - } - - if (serial_have_data == 0) - { - f = read(serialfd, buf, 1); - - if (f > 0) - { - Log(TLOG_DEBUG, "serial", "Have data from serial [%d]!", f); - fflush(stdout); - serial_have_data = 0x01; - serial_data = buf[0]; - } - } - - if (serial_have_data > 0) - { - /* Gen an int if enabled */ - if (ws_ioRam[0xB2] & 0x04) - { - ws_ioRam[0xb6] &= ~0x04; - Log(TLOG_DEBUG, "serial", "SERIAL INNNNNTTTT!!!!!!!"); - nec_int((ws_ioRam[0xb0] + 3) * 4); - } - } -} - -unsigned char read_serial() -{ - unsigned char buf[10]; - int f; - - if (serialfd < 0) - { - return 0xFF; - } - - if (serial_have_data > 0) - { - serial_have_data = 0; - return serial_data; - } - - f = read(serialfd, buf, 1); - - if (f == 1) - { - return buf[0]; - } - - return 0x42; -} - -void write_serial(unsigned char value) -{ - if (serialfd < 0) - { - return; - } - - write(serialfd, &value, 1); -} - - //////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////// @@ -351,22 +182,46 @@ void write_serial(unsigned char value) // // //////////////////////////////////////////////////////////////////////////////// +uint8_t io_readport_new(uint8_t port) +{ + if (io_registry[port].read) + { + return io_registry[port].read(io_registry[port].private, port); + } + return 0x90; +} + +void io_writeport_new(uint8_t port, uint8_t value) +{ + if (io_registry[port].write) + { + return io_registry[port].write(io_registry[port].private, port, value); + } +} + +void register_io_hook(uint8_t port, io_read *readHook, io_write writeHook, void *pdata) +{ + io_registry[port].read = readHook; + io_registry[port].write = writeHook; + io_registry[port].private = pdata; +} + +void register_io_hook_array(uint8_t *portList, uint8_t listLen, io_read *readHook, io_write writeHook, void *pdata) +{ + uint16_t i; + for(i = 0; i < listLen; i++) + { + io_registry[portList[i]].read = readHook; + io_registry[portList[i]].write = writeHook; + io_registry[portList[i]].private = pdata; + } +} + uint8_t io_readport(uint8_t port) { int w1, w2; uint8_t retVal = 0; - /* - if (port > 0x100) - { - port &= 0xFF; - if (port > 0x100) - { - return 0x00; - } - } - */ - switch (port) { case 0x4e: @@ -425,25 +280,7 @@ uint8_t io_readport(uint8_t port) break; - case 0xbe: // internal eeprom status/command register - // ack eeprom write - if (ws_ioRam[0xbe] & 0x20) - { - retVal = ws_ioRam[0xbe] | 2; - break; - } - - // ack eeprom read - if (ws_ioRam[0xbe] & 0x10) - { - retVal = ws_ioRam[0xbe] | 1; - break; - } - - // else ack both - retVal = ws_ioRam[0xbe] | 3; - break; case 0x62: switch (ws_get_system()) @@ -460,134 +297,17 @@ uint8_t io_readport(uint8_t port) } break; - case 0xba: // eeprom even byte read - retVal = iee_Databuffer & 0x00FF; - break; - case 0xbb: // eeprom odd byte read - retVal = (iee_Databuffer & 0xFF00) >> 8; - break; case 0xc0 : // ??? retVal = ((ws_ioRam[0xc0] & 0xf) | 0x20); goto exit; - case 0xC8: - // ack eeprom write - if (ws_ioRam[0xbe] & 0x20) - { - retVal = ws_ioRam[0xbe] | 2; - break; - } - - // ack eeprom read - if (ws_ioRam[0xbe] & 0x10) - { - retVal = ws_ioRam[0xbe] | 1; - break; - } - - // else ack both - retVal = ws_ioRam[0xbe] | 3; - break; - - case 0xC4: // eeprom even byte read - return cee_Databuffer & 0x00FF; - - case 0xC5: // eeprom odd byte read - return (cee_Databuffer & 0xFF00) >> 8; - - case 0xca : // RTC Command and status register - // set ack to always 1 - retVal = (ws_ioRam[0xca] | 0x80); - goto exit; - - case 0xcb : // RTC data register - - if (ws_ioRam[0xca] == 0x15) // get time command - { - struct tm *newtime; - time_t long_time; - time(&long_time); - newtime = localtime(&long_time); - -#define BCD(value) ((value/10)<<4)|(value%10) - - switch (rtcDataRegisterReadCount) - { - case 0: - rtcDataRegisterReadCount++; - retVal = BCD(newtime->tm_year - 100); - goto exit; - - case 1: - rtcDataRegisterReadCount++; - retVal = BCD(newtime->tm_mon); - goto exit; - - case 2: - rtcDataRegisterReadCount++; - retVal = BCD(newtime->tm_mday); - goto exit; - - case 3: - rtcDataRegisterReadCount++; - retVal = BCD(newtime->tm_wday); - goto exit; - - case 4: - rtcDataRegisterReadCount++; - retVal = BCD(newtime->tm_hour); - goto exit; - - case 5: - rtcDataRegisterReadCount++; - retVal = BCD(newtime->tm_min); - goto exit; - - case 6: - rtcDataRegisterReadCount = 0; - retVal = BCD(newtime->tm_sec); - goto exit; - } - - return 0; - } - else - { - // set ack - retVal = (ws_ioRam[0xcb] | 0x80); - goto exit; - } - case 0xD0: retVal = 0; goto exit; - /* Serial port link.. */ - case 0xB1: - retVal = read_serial(); - Log(TLOG_DEBUG, "serial", "Read %02X", retVal); - goto exit; - - case 0xB3: - check_serial_data(); - - if (ws_ioRam[0xB3] & 0x80) - { - retVal = (ws_ioRam[0xB3] & ~1) | serial_have_data | 0x04; - } - else - { - retVal = 0x00; - } - - Log(TLOG_DEBUG, "serial", "<<< 0xD0) { - Log(TLOG_DEBUG, "io", "ReadIO %02X <= %02X", port, retVal); + Log(TLOG_DEBUG, "io", "ReadIO(%02X) <= %02X [%04X:%04Xh];", port, retVal, I.sregs[CS], I.ip); } break; @@ -611,10 +331,14 @@ uint8_t io_readport(uint8_t port) } + if (port == 0xA0) + { + Log(TLOG_ALWAYS, "A0", "Hello I'm A0 and read %02X!!!", retVal); + } if (port >= 0xC4) { - Log(TLOG_DEBUG, "io", "ReadMBCIO(%02X) <= %02X", port, retVal); + Log(TLOG_DEBUG, "io", "ReadMBCIO(%02X) <= %02X [%04X:%04Xh];", port, retVal, I.sregs[CS], I.ip); } @@ -633,7 +357,7 @@ exit: break; default: - Log(TLOG_DEBUG, "io", "ReadIO %02X <= %02X", port, retVal); + Log(TLOG_DEBUG, "io", "ReadIO(%02X) <= %02X [%04X:%04Xh];", port, retVal, I.sregs[CS], I.ip); break; } } @@ -804,23 +528,30 @@ void io_writeport(uint32_t port, uint8_t value) // bit 7 set to start dma transfer if (value & 0x80) { - int dma_start = (((uint32_t)ws_ioRam[0x41]) << 8) | (((uint32_t)ws_ioRam[0x40])) | - (((uint32_t)ws_ioRam[0x42]) << 16); - int dma_end = (((uint32_t)ws_ioRam[0x45]) << 8) | (((uint32_t)ws_ioRam[0x44])) | - (((uint32_t)ws_ioRam[0x43]) << 16); - int dma_size = (((uint32_t)ws_ioRam[0x47]) << 8) | (((uint32_t)ws_ioRam[0x46])); + uint32_t dma_start = (ws_ioRam[0x41] << 8) | (ws_ioRam[0x40]) | (ws_ioRam[0x42] << 16); + uint32_t dma_dest = (ws_ioRam[0x45] << 8) | (ws_ioRam[0x44]) | (ws_ioRam[0x43] << 16); + uint32_t dma_size = (ws_ioRam[0x47] << 8) | (ws_ioRam[0x46]); - for (int ix = 0 ; ix < dma_size ; ix++) + uint8_t dma_inc = (value & 0x01) ? -1: 1; + + Log(TLOG_VERBOSE, "DMA", "Starting DMA from %08X to %08X (len: %08X, inc: %d)", + dma_start, dma_dest, dma_size, dma_inc); + + + + for (uint32_t ix = 0 ; ix < dma_size ; ix++) { - mem_writemem20(dma_end++, mem_readmem20(dma_start++)); + mem_writemem20(dma_dest, mem_readmem20(dma_start)); + dma_start += dma_inc; + dma_dest += dma_inc; } ws_ioRam[0x47] = 0; ws_ioRam[0x46] = 0; ws_ioRam[0x41] = (uint8_t)(dma_start >> 8); ws_ioRam[0x40] = (uint8_t)(dma_start & 0xff); - ws_ioRam[0x45] = (uint8_t)(dma_end >> 8); - ws_ioRam[0x44] = (uint8_t)(dma_end & 0xff); + ws_ioRam[0x45] = (uint8_t)(dma_dest >> 8); + ws_ioRam[0x44] = (uint8_t)(dma_dest & 0xff); ws_ioRam[0x48] = 0; } @@ -842,6 +573,19 @@ void io_writeport(uint32_t port, uint8_t value) /* GPU (again) */ case 0x60: +#ifdef USE_PAGED_MEMORY_ACCESS + if (ws_get_system() != WS_SYSTEM_MONO) + { + if (value & 0x80) + { + set_iram_access(IRAM_FULL_ACCESS); + } + else + { + set_iram_access(IRAM_LIMITED_ACCESS); + } + } +#endif break; /* System */ @@ -890,16 +634,17 @@ void io_writeport(uint32_t port, uint8_t value) /* Force cart handshake to be set */ ws_ioRam[port] |= 0x80; -#ifdef USE_PAGED_MEMORY_ACCESS if (value & 0x01) { Log(TLOG_WARNING, "A0", "Oh yeah %02X BABY", value); +#ifdef USE_PAGED_MEMORY_ACCESS uint32_t romSize; uint8_t *rom = getRom(&romSize); set_memory_bank(0xF, ws_get_page_ptr(rom, romSize, (ws_ioRam[0xC0] & 0x0F << 4) + 0x0F)); +#endif } break; -#endif + /* Timers */ case 0xA2: case 0xA4: @@ -920,169 +665,10 @@ void io_writeport(uint32_t port, uint8_t value) case 0xB6: break; - /* Serial */ - case 0xB1: - write_serial(value); - break; - - case 0xB3: - Log(TLOG_DEBUG, "serial", ">>>>RS232STA: %02X [%c%c%cxx%c%c%c]", value, (value & 0x80) ? 'E' : 'd', (value & 0x40) ? '3' : '9', - (value & 0x20) ? 'R' : 'n', (value & 0x04) ? 'E' : 'f', (value & 0x02) ? 'V' : 'n', - (value & 0x01) ? 'D' : 'e'); - - /* Serial status: 7 = Enable, 6 = baudrate, 5 = Overrun reset - 2 = Send Buffer empty - 1 = Overrun - 0 = Data Received - */ - serial_speed = ((value & 040) == 0x00) ? BDR_9600 : BDR_38400; - - if ((value & 0x80) == 0x80) - { - open_serial(); - set_baudrate(serial_speed); - check_serial_data(); - } - - break; - /* buttons */ case 0xB5: break; - /* Internal EEPROM */ - case 0xba: /* DATA Low */ - iee_Databuffer = iee_Databuffer & 0xFF00; - iee_Databuffer = iee_Databuffer | (value); - break; - - case 0xbb: /* Data High */ - iee_Databuffer = iee_Databuffer & 0x00FF; - iee_Databuffer = iee_Databuffer | (value << 8); - break; - - case 0xBC: /* Address Low */ - case 0xBD: /* Address High */ - break; - - case 0xBE: /* Command / Status */ - { - uint16_t address, command, subcmd; - - iee_SelAddress = (ws_ioRam[0xBD] << 8) | ws_ioRam[0xBC]; - - if (ws_gpu_operatingInColor) - { - /* - 13 00 - S CCaa AAAA AAAA - 0001 0011 0000 0000 - - */ - /* S CC aaAAAAAAAA */ - command = (iee_SelAddress >> 10) & 0x3; - address = iee_SelAddress & 0x3FF; - subcmd = (iee_SelAddress >> 8) & 0x03; - } - else - { - /* S CC aaAAAA */ - command = (iee_SelAddress >> 6) & 0x3; - address = iee_SelAddress & 0x3F; - subcmd = (iee_SelAddress >> 4) & 0x03; - } - - - if (command == EEPROM_SUBCOMMAND) - { - command = EEPROM_WRITEDISABLE + subcmd; - } -#ifdef EEPROM_DEBUG - printf("IEEP: RA:%04X RD:%04X A:%03X C:%s", iee_SelAddress, iee_Databuffer, address, eii_CommandName[command]); -#endif - if (value & 0x40) - { - /* Sub command */ -#ifdef EEPROM_DEBUG - printf(" - Sub"); -#endif - if (command == EEPROM_WRITEENABLE) - { -#ifdef EEPROM_DEBUG - printf(" Write Enable\n"); -#endif - iee_WriteEnable = true; - } - else if (command == EEPROM_WRITEDISABLE) - { -#ifdef EEPROM_DEBUG - printf(" Write Disable\n"); -#endif - iee_WriteEnable = false; - } - else if (command == EEPROM_ERASEALL) - { -#ifdef EEPROM_DEBUG - printf(" Erase All\n"); -#endif - if (ws_gpu_operatingInColor) - { - memset(internalEeprom, 0, COLOR_IEEPROM_SIZE); - } - else - { - memset(internalEeprom, 0, BW_IEEPROM_SIZE); - } - } -#ifdef EEPROM_DEBUG - else - { - printf(" Write All?\n"); - } -#endif - } - else if (value & 0x20) - { - /* Write */ -#ifdef EEPROM_DEBUG - printf(" - Write?"); -#endif - if (iee_WriteEnable) - { -#ifdef EEPROM_DEBUG - printf(" Yes : %04X\n", iee_Databuffer); -#endif - internalEeprom[address] = iee_Databuffer; - } -#ifdef EEPROM_DEBUG - else - { - printf(" No\n"); - } -#endif - } - else if (value & 0x10) - { - /* Read */ -#ifdef EEPROM_DEBUG - printf(" - Read"); -#endif - iee_Databuffer = internalEeprom[address]; -#ifdef EEPROM_DEBUG - printf(" Data : %04X\n", iee_Databuffer); -#endif - } -#ifdef EEPROM_DEBUG - else - { - printf(" Unknown value: %02X\n", value); - } -#endif - fflush(stdout); - } - break; - - /* MBC */ #ifndef USE_PAGED_MEMORY_ACCESS case 0xC0: @@ -1140,116 +726,6 @@ void io_writeport(uint32_t port, uint8_t value) #endif - /* Cart EEPROM */ - case 0xC4: /* Data High */ - cee_Databuffer = cee_Databuffer & 0xFF00; - cee_Databuffer = cee_Databuffer | (value); - break; - - case 0xC5: /* Data High */ - cee_Databuffer = cee_Databuffer & 0x00FF; - cee_Databuffer = cee_Databuffer | (value << 8); - break; - - case 0xC6: /* Address Low */ - case 0xC7: /* Address High */ - break; - - case 0xC8: /* Command / Status */ - { - uint16_t address, command, subcmd; /*, start;*/ - - cee_SelAddress = (ws_ioRam[0xBD] << 8) | ws_ioRam[0xBC]; - - /* S CC aaAAAA */ - command = (cee_SelAddress >> 6) & 0x3; - address = cee_SelAddress & 0x3F; - subcmd = (cee_SelAddress >> 4) & 0x03; - - - if (command == EEPROM_SUBCOMMAND) - { - command = EEPROM_WRITEDISABLE + subcmd; - } - - printf("CEEP: RA:%04X RD:%04X A:%03X C:%s", cee_SelAddress, cee_Databuffer, address, eii_CommandName[command]); - - if (value & 0x40) - { - /* Sub command */ - printf(" - Sub"); - if (command == EEPROM_WRITEENABLE) - { - printf(" Write Enable\n"); - cee_WriteEnable = true; - } - else if (command == EEPROM_WRITEDISABLE) - { - printf(" Write Disable\n"); - cee_WriteEnable = false; - } - else if (command == EEPROM_ERASEALL) - { - printf(" Erase All\n"); - /* Nothing here at the moment */ - } - else - { - printf(" Write All?\n"); - } - } - else if (value & 0x20) - { - /* Write */ - printf(" - Write?"); - if (cee_WriteEnable) - { - printf(" Yes : %04X\n", cee_Databuffer); - externalEeprom[address] = cee_Databuffer; - } - else - { - printf(" No\n"); - } - } - else if (value & 0x10) - { - /* Read */ - printf(" - Read"); - cee_Databuffer = externalEeprom[address]; - printf(" Data : %04X\n", cee_Databuffer); - } - else - { - printf(" Unknown value: %02X@", value); - } - fflush(stdout); - } - break; - - case 0xca: - if (value == 0x15) - { - rtcDataRegisterReadCount = 0; - } - - break; - break; - - case 0xCB: - break; - - case 0xF0: - break; - - case 0xF1: - printf("%d\n", (signed short)((value << 8) | ws_ioRam[0xF0])); - break; - - case 0xF2: - printf("%c", value); - fflush(stdout); - break; case 0xB7: break; /* Somwthing to write there, but what? */ @@ -1262,9 +738,28 @@ void io_writeport(uint32_t port, uint8_t value) { Log(TLOG_DEBUG, "io", "WriteIO(%02X, %02X) [%04X:%04Xh];", port, value, I.sregs[CS], I.ip); } - if (port >= 0xC4) { - Log(TLOG_DEBUG, "io", "WriteMBCIO(%02X, %02X);", port, value); + Log(TLOG_DEBUG, "io", "WriteMBCIO(%02X, %02X) [%04X:%04Xh];", port, value, I.sregs[CS], I.ip); } + + + if (port < 0xC0) + { + switch(port) + { + case 0x05: case 0x06: + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x1C: case 0x1D: case 0x1E: case 0x1F: + case 0xB5: + case 0xB6: + break; + + default: + Log(TLOG_DEBUG, "io", "WriteIO(%02X, %02X) [%04X:%04Xh];", port, value, I.sregs[CS], I.ip); + break; + } + } + + } diff --git a/source/memory.c b/source/memory.c index 74c336c..d23c0c4 100644 --- a/source/memory.c +++ b/source/memory.c @@ -28,14 +28,14 @@ #include #include #include -#include "ws.h" -#include "log.h" -#include "rom.h" -#include "./nec/nec.h" -#include "io.h" -#include "gpu.h" -#include "audio.h" -#include "memory.h" +#include +#include +#include +#include "nec.h" +#include +#include +#include +#include //////////////////////////////////////////////////////////////////////////////// // @@ -330,6 +330,47 @@ uint8_t *getSram(uint32_t *size) *size = sramSize; return ws_staticRam; } + +void set_iram_access(iram_access_t mode) +{ + /* IRAM */ + set_memory_bank(0, internalRam); + + if (mode == IRAM_LIMITED_ACCESS) + { + for (int i = 0x4 ; i < 0x10 ; i++) + { + set_memory_page(i, NULL); + } + } +} + +void mem_dump_info() +{ + if (ws_get_system() == WS_SYSTEM_MONO) + { + Log(TLOG_VERBOSE, "MEM", "System is B&W"); + Log(TLOG_VERBOSE, "MEM", "internal ROM: %09p", internalBWIRom); + } + else if (ws_get_system() == WS_SYSTEM_COLOR) + { + Log(TLOG_VERBOSE, "MEM", "System is Color"); + Log(TLOG_VERBOSE, "MEM", "internal ROM: %09p", internalColorIRom); + } + else if (ws_get_system() == WS_SYSTEM_CRYSTAL) + { + Log(TLOG_VERBOSE, "MEM", "System is Crystal"); + Log(TLOG_VERBOSE, "MEM", "internal ROM: %09p", internalCrystalIRom); + } + + Log(TLOG_VERBOSE, "MEM", "internal RAM: %p", internalRam); + Log(TLOG_VERBOSE, "MEM", "Cart : %p", ws_rom); + for(int i = 0; i < 0x100; i += 4) + { + Log(TLOG_VERBOSE, "MEM", "Page %02X [%011p] | Page %02X [%011p] | Page %02X [%011p] | Page %02X [%011p]", + i, pagedMemory[i], i+1, pagedMemory[i+1], i+2, pagedMemory[i+2], i+3, pagedMemory[i+3]); + } +} #endif //////////////////////////////////////////////////////////////////////////////// // @@ -482,12 +523,12 @@ void ws_memory_init(uint8_t *rom, uint32_t wsRomSize) ws_haveColorIRom = false; ws_haveCrystalIRom = false; - if (internalColorIRom != NULL) + if (internalBWIRom != NULL) { Log(TLOG_DEBUG, "memory", "B&W IROM Found!"); ws_haveColorIRom = true; } - if (internalBWIRom != NULL) + if (internalColorIRom != NULL) { Log(TLOG_DEBUG, "memory", "Color IROM Found!"); ws_haveBWIRom = true; @@ -507,12 +548,8 @@ void ws_memory_init(uint8_t *rom, uint32_t wsRomSize) pagedMemory[i] = NULL; } - /* IRAM */ - set_memory_bank(0, internalRam); - for(int i = 0x4; i < 0x10; i++) - { - set_memory_page(i, NULL); - } + /* We start in B&W mode */ + set_iram_access(IRAM_LIMITED_ACCESS); /* Cart SRAM */ if (sramSize > 0) @@ -527,6 +564,7 @@ void ws_memory_init(uint8_t *rom, uint32_t wsRomSize) { set_memory_bank(i, ws_get_page_ptr(ws_rom, romSize, 0xF0 + i)); } + mem_dump_info(); set_irom_overlay(); #endif diff --git a/source/nec/CMakeLists.txt b/source/nec/CMakeLists.txt index d4dcf97..90dc40e 100644 --- a/source/nec/CMakeLists.txt +++ b/source/nec/CMakeLists.txt @@ -1,6 +1,6 @@ set(SOURCES nec.c nec_debugger.c) -set(HEADERS nec.h necea.h necinstr.h necintrf.h necmodrm.h nec_debugger.h) +set(HEADERS ../includes/nec.h necea.h necinstr.h ../includes/necintrf.h necmodrm.h ../includes/nec_debugger.h) add_library(nec_v30 ${SOURCES} ${HEADERS}) -target_include_directories(nec_v30 PUBLIC . ..) \ No newline at end of file +target_include_directories(nec_v30 PUBLIC ../includes/) \ No newline at end of file diff --git a/source/nec/nec.c b/source/nec/nec.c index c6e2397..69efe87 100644 --- a/source/nec/nec.c +++ b/source/nec/nec.c @@ -40,12 +40,12 @@ #include -#include "memory.h" -#include "io.h" +#include +#include -#include "nec.h" -#include "necintrf.h" -#include "nec_debugger.h" +#include +#include +#include /***************************************************************************/ /* cpu state */ @@ -4225,21 +4225,21 @@ int nec_execute(int cycles) while (nec_ICount > 0) { #if 0 - if ((I.sregs[CS] == 0xF000) && (I.ip >= 0x0000) ) + if ( ws_ioRam[0xA0] & 0x01 ) { int tmp; char buffer[256]; uint8_t op = mem_readmem20((I.sregs[CS] << 4) + I.ip); //Log(TLOG_NORMAL, "NEC v30", "[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip, op, instructionsName[op], I.IF); - printf("AX: %04X, BX: %04X, CX: %04X, DX: %04X, SI: %04X, DI: %04X, SP: %04X\n", + fprintf(stderr, "AX: %04X, BX: %04X, CX: %04X, DX: %04X, SI: %04X, DI: %04X, SP: %04X\n", I.regs.w[AW], I.regs.w[BW], I.regs.w[CW], I.regs.w[DW], I.regs.w[IX], I.regs.w[IY], I.regs.w[SP]); - printf("CS: %04X, DS: %04X, SS: %04X, ES: %04X\n", + fprintf(stderr, "CS: %04X, DS: %04X, SS: %04X, ES: %04X\n", I.sregs[CS], I.sregs[DS], I.sregs[SS], I.sregs[ES]); memset(buffer, 0, 256); nec_decode_instruction(I.sregs[CS], I.ip, buffer, 255); - printf("[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip, op, buffer, I.IF); - tmp = getchar(); + fprintf(stderr, "[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip, op, buffer, I.IF); + //tmp = getchar(); } #endif nec_instruction[FETCHOP](); diff --git a/source/nec/nec_debugger.c b/source/nec/nec_debugger.c index 36dbe37..0e81529 100644 --- a/source/nec/nec_debugger.c +++ b/source/nec/nec_debugger.c @@ -11,10 +11,10 @@ #include #include -#include "log.h" -#include "nec_debugger.h" -#include "necintrf.h" -#include "memory.h" +#include +#include +#include +#include /*** * Note: the while code to decode instruction is not meant to be optimised, but to be easy to maintain. diff --git a/source/peripherals/buttons.c b/source/peripherals/buttons.c new file mode 100644 index 0000000..cffde38 --- /dev/null +++ b/source/peripherals/buttons.c @@ -0,0 +1,9 @@ +/* + * NewOswan + * buttons.c: + * + * Created by Manoël Trapier on 19/12/2021. + * Copyright (c) 2014-2021 986-Studio. All rights reserved. + * + */ + diff --git a/source/peripherals/color_system.c b/source/peripherals/color_system.c new file mode 100644 index 0000000..8b49be2 --- /dev/null +++ b/source/peripherals/color_system.c @@ -0,0 +1,9 @@ +/* + * NewOswan + * color_system.c: IO specific to the WonderSwan Color systems. + * + * Created by Manoël Trapier on 19/12/2021. + * Copyright (c) 2014-2021 986-Studio. All rights reserved. + * + */ + diff --git a/source/peripherals/debug.c b/source/peripherals/debug.c new file mode 100644 index 0000000..f583688 --- /dev/null +++ b/source/peripherals/debug.c @@ -0,0 +1,36 @@ +/* + * NewOswan + * debug.c: + * + * Created by Manoël Trapier on 19/12/2021. + * Copyright (c) 2014-2021 986-Studio. All rights reserved. + * + */ + +#include +#include + +extern uint8_t *ws_ioRam; + +uint8_t debug_io_read(void *pdata, uint8_t port) +{ + switch (port) + { + + } +} + +void debug_io_write(void *pdata, uint8_t port, uint8_t value) +{ + switch (port) + { + case 0xF1: + printf("%d\n", (signed short)((value << 8) | ws_ioRam[0xF0])); + break; + + case 0xF2: + printf("%c", value); + fflush(stdout); + break; + } +} \ No newline at end of file diff --git a/source/peripherals/dma.c b/source/peripherals/dma.c new file mode 100644 index 0000000..a44f32b --- /dev/null +++ b/source/peripherals/dma.c @@ -0,0 +1,9 @@ +/* + * NewOswan + * dma.c: + * + * Created by Manoël Trapier on 19/12/2021. + * Copyright (c) 2014-2021 986-Studio. All rights reserved. + * + */ + diff --git a/source/peripherals/eeprom.c b/source/peripherals/eeprom.c new file mode 100644 index 0000000..7fa9790 --- /dev/null +++ b/source/peripherals/eeprom.c @@ -0,0 +1,336 @@ +/* + * NewOswan + * eeprom.c: + * + * Created by Manoël Trapier on 19/12/2021. + * Copyright (c) 2014-2021 986-Studio. All rights reserved. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +extern uint8_t *externalEeprom; +extern uint16_t *internalEeprom; + +enum +{ + EEPROM_SUBCOMMAND = 0, /* 00 00 */ + EEPROM_WRITE, /* 01 xx */ + EEPROM_READ, /* 10 xx */ + EEPROM_ERASE, /* 11 xx */ + EEPROM_WRITEDISABLE, /* 00 00 */ + EEPROM_WRITEALL, /* 00 01 */ + EEPROM_ERASEALL, /* 00 10 */ + EEPROM_WRITEENABLE /* 00 11 */ +}; + +char *eii_CommandName[] = { + "SUB", "WRI", "RED", "ERA", "WRD", "WRA", "ERL", "WRE", +}; + +uint8_t iee_WriteEnable = false; +uint16_t iee_SelAddress = 0; +uint16_t iee_Databuffer = 0; +uint8_t iee_Mode = EEPROM_READ; + +uint8_t cee_WriteEnable = true; +uint16_t cee_SelAddress = 0; +uint16_t cee_Databuffer = 0; +uint8_t cee_Mode = EEPROM_READ; + +// TODO: temporary +extern uint8_t *ws_ioRam; + +uint8_t rs232_io_read(void *pdata, uint8_t port) +{ + uint8_t retVal; + switch (port) + { + case 0xba: // eeprom even byte read + retVal = iee_Databuffer & 0x00FF; + break; + + case 0xbb: // eeprom odd byte read + retVal = (iee_Databuffer & 0xFF00) >> 8; + break; + + case 0xbe: // internal eeprom status/command register + // ack eeprom write + if (ws_ioRam[0xbe] & 0x20) + { + retVal = ws_ioRam[0xbe] | 2; + break; + } + + // ack eeprom read + if (ws_ioRam[0xbe] & 0x10) + { + retVal = ws_ioRam[0xbe] | 1; + break; + } + + // else ack both + retVal = ws_ioRam[0xbe] | 3; + break; + case 0xC8: + // ack eeprom write + if (ws_ioRam[0xbe] & 0x20) + { + retVal = ws_ioRam[0xbe] | 2; + break; + } + + // ack eeprom read + if (ws_ioRam[0xbe] & 0x10) + { + retVal = ws_ioRam[0xbe] | 1; + break; + } + + // else ack both + retVal = ws_ioRam[0xbe] | 3; + break; + case 0xC4: // eeprom even byte read + return cee_Databuffer & 0x00FF; + case 0xC5: // eeprom odd byte read + return (cee_Databuffer & 0xFF00) >> 8; + } +} + +void rs232_io_write(void *pdata, uint8_t port, uint8_t value) +{ + uint8_t retVal; + switch (port) + { + /* Internal EEPROM */ + case 0xba: /* DATA Low */ + iee_Databuffer = iee_Databuffer & 0xFF00; + iee_Databuffer = iee_Databuffer | (value); + break; + + case 0xbb: /* Data High */ + iee_Databuffer = iee_Databuffer & 0x00FF; + iee_Databuffer = iee_Databuffer | (value << 8); + break; + + case 0xBC: /* Address Low */ + case 0xBD: /* Address High */ + break; + + case 0xBE: /* Command / Status */ + { + uint16_t address, command, subcmd; + + iee_SelAddress = (ws_ioRam[0xBD] << 8) | ws_ioRam[0xBC]; + + if (ws_gpu_operatingInColor) + { + /* + 13 00 + S CCaa AAAA AAAA + 0001 0011 0000 0000 + + */ + /* S CC aaAAAAAAAA */ + command = (iee_SelAddress >> 10) & 0x3; + address = iee_SelAddress & 0x3FF; + subcmd = (iee_SelAddress >> 8) & 0x03; + } + else + { + /* S CC aaAAAA */ + command = (iee_SelAddress >> 6) & 0x3; + address = iee_SelAddress & 0x3F; + subcmd = (iee_SelAddress >> 4) & 0x03; + } + + + if (command == EEPROM_SUBCOMMAND) + { + command = EEPROM_WRITEDISABLE + subcmd; + } +#ifdef EEPROM_DEBUG + printf("IEEP: RA:%04X RD:%04X A:%03X C:%s", iee_SelAddress, iee_Databuffer, address, eii_CommandName[command]); +#endif + if (value & 0x40) + { + /* Sub command */ +#ifdef EEPROM_DEBUG + printf(" - Sub"); +#endif + if (command == EEPROM_WRITEENABLE) + { +#ifdef EEPROM_DEBUG + printf(" Write Enable\n"); +#endif + iee_WriteEnable = true; + } + else if (command == EEPROM_WRITEDISABLE) + { +#ifdef EEPROM_DEBUG + printf(" Write Disable\n"); +#endif + iee_WriteEnable = false; + } + else if (command == EEPROM_ERASEALL) + { +#ifdef EEPROM_DEBUG + printf(" Erase All\n"); +#endif + if (ws_gpu_operatingInColor) + { + memset(internalEeprom, 0, COLOR_IEEPROM_SIZE); + } + else + { + memset(internalEeprom, 0, BW_IEEPROM_SIZE); + } + } +#ifdef EEPROM_DEBUG + else + { + printf(" Write All?\n"); + } +#endif + } + else if (value & 0x20) + { + /* Write */ +#ifdef EEPROM_DEBUG + printf(" - Write?"); +#endif + if (iee_WriteEnable) + { +#ifdef EEPROM_DEBUG + printf(" Yes : %04X\n", iee_Databuffer); +#endif + internalEeprom[address] = iee_Databuffer; + } +#ifdef EEPROM_DEBUG + else + { + printf(" No\n"); + } +#endif + } + else if (value & 0x10) + { + /* Read */ +#ifdef EEPROM_DEBUG + printf(" - Read"); +#endif + iee_Databuffer = internalEeprom[address]; +#ifdef EEPROM_DEBUG + printf(" Data : %04X\n", iee_Databuffer); +#endif + } +#ifdef EEPROM_DEBUG + else + { + printf(" Unknown value: %02X\n", value); + } +#endif + fflush(stdout); + } + break; + + /* Cart EEPROM */ + case 0xC4: /* Data High */ + cee_Databuffer = cee_Databuffer & 0xFF00; + cee_Databuffer = cee_Databuffer | (value); + break; + + case 0xC5: /* Data High */ + cee_Databuffer = cee_Databuffer & 0x00FF; + cee_Databuffer = cee_Databuffer | (value << 8); + break; + + case 0xC6: /* Address Low */ + case 0xC7: /* Address High */ + break; + + case 0xC8: /* Command / Status */ + { + uint16_t address, command, subcmd; /*, start;*/ + + cee_SelAddress = (ws_ioRam[0xBD] << 8) | ws_ioRam[0xBC]; + + /* S CC aaAAAA */ + command = (cee_SelAddress >> 6) & 0x3; + address = cee_SelAddress & 0x3F; + subcmd = (cee_SelAddress >> 4) & 0x03; + + + if (command == EEPROM_SUBCOMMAND) + { + command = EEPROM_WRITEDISABLE + subcmd; + } + + printf("CEEP: RA:%04X RD:%04X A:%03X C:%s", cee_SelAddress, cee_Databuffer, address, eii_CommandName[command]); + + if (value & 0x40) + { + /* Sub command */ + printf(" - Sub"); + if (command == EEPROM_WRITEENABLE) + { + printf(" Write Enable\n"); + cee_WriteEnable = true; + } + else if (command == EEPROM_WRITEDISABLE) + { + printf(" Write Disable\n"); + cee_WriteEnable = false; + } + else if (command == EEPROM_ERASEALL) + { + printf(" Erase All\n"); + /* Nothing here at the moment */ + } + else + { + printf(" Write All?\n"); + } + } + else if (value & 0x20) + { + /* Write */ + printf(" - Write?"); + if (cee_WriteEnable) + { + printf(" Yes : %04X\n", cee_Databuffer); + externalEeprom[address] = cee_Databuffer; + } + else + { + printf(" No\n"); + } + } + else if (value & 0x10) + { + /* Read */ + printf(" - Read"); + cee_Databuffer = externalEeprom[address]; + printf(" Data : %04X\n", cee_Databuffer); + } + else + { + printf(" Unknown value: %02X@", value); + } + fflush(stdout); + } + break; + + case 0xCB: + break; + + } +} diff --git a/source/peripherals/mono_system.c b/source/peripherals/mono_system.c new file mode 100644 index 0000000..042d622 --- /dev/null +++ b/source/peripherals/mono_system.c @@ -0,0 +1,9 @@ +/* + * NewOswan + * mono_system.c: IOs specific to the original WonderSwan + * + * Created by Manoël Trapier on 19/12/2021. + * Copyright (c) 2014-2021 986-Studio. All rights reserved. + * + */ + diff --git a/source/peripherals/rs232.c b/source/peripherals/rs232.c new file mode 100644 index 0000000..fc9408c --- /dev/null +++ b/source/peripherals/rs232.c @@ -0,0 +1,230 @@ +/* + * NewOswan + * rs232.c: + * + * Created by Manoël Trapier on 19/12/2021. + * Copyright (c) 2014-2021 986-Studio. All rights reserved. + * + */ + +#include +#include + +#include /* UNIX standard function definitions */ +#include /* Error number definitions */ +#include /* POSIX terminal control definitions */ +#include +#include + +#include +#include + +/* Temporary */ +extern uint8_t *ws_ioRam; + +/* Serial port */ +#define BDR_9600 (0) +#define BDR_38400 (1) +#define SERIAL_PORT "/dev/tty.USA19H141P1.1" +static int serialfd = -1; +static int serial_have_data = 0; +static unsigned char serial_data = 0; +static int serial_speed = BDR_9600; + +static void open_serial() +{ + if (serialfd < 0) + { + serialfd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY); + + //set_baudrate(serial_speed); + serial_have_data = 0; + } +} + +static void set_baudrate(int speed) +{ + struct termios options; + + if (serialfd < 0) + { + return; + } + + tcgetattr(serialfd, &options); + + options.c_cflag &= ~PARENB; + options.c_cflag &= ~CSTOPB; + options.c_cflag &= ~CSIZE; + options.c_cflag |= CS8; + + if (speed == BDR_9600) + { + cfsetispeed(&options, B9600); + } + else + { + cfsetospeed(&options, B38400); + } + +#if 0 + options.c_cflag &= ~CNEW_RTSCTS; +#else + options.c_cflag &= ~CRTSCTS; +#endif + options.c_cflag |= (CLOCAL | CREAD); + + options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + + options.c_oflag &= ~OPOST; + + tcsetattr(serialfd, TCSANOW, &options); + + /* Make sure read is not blocking */ + fcntl(serialfd, F_SETFL, FNDELAY); +} + +static void close_serial() +{ + close(serialfd); + serialfd = -1; +} + +static void check_serial_data() +{ + unsigned char buf[10]; + int f; + + if (serialfd < 0) + { + return; + } + + if (serial_have_data == 0) + { + f = read(serialfd, buf, 1); + + if (f > 0) + { + Log(TLOG_DEBUG, "serial", "Have data from serial [%d]!", f); + fflush(stdout); + serial_have_data = 0x01; + serial_data = buf[0]; + } + } + + if (serial_have_data > 0) + { + /* Gen an int if enabled */ + if (ws_ioRam[0xB2] & 0x04) + { + ws_ioRam[0xb6] &= ~0x04; + Log(TLOG_DEBUG, "serial", "SERIAL INNNNNTTTT!!!!!!!"); + nec_int((ws_ioRam[0xb0] + 3) * 4); + } + } +} + +static unsigned char read_serial() +{ + unsigned char buf[10]; + int f; + + if (serialfd < 0) + { + return 0xFF; + } + + if (serial_have_data > 0) + { + serial_have_data = 0; + return serial_data; + } + + f = read(serialfd, buf, 1); + + if (f == 1) + { + return buf[0]; + } + + return 0x42; +} + +static void write_serial(unsigned char value) +{ + if (serialfd < 0) + { + return; + } + + write(serialfd, &value, 1); +} + +uint8_t rs232_io_read(void *pdata, uint8_t port) +{ + uint8_t retVal; + switch(port) + { + case 0xB1: + retVal = read_serial(); + Log(TLOG_DEBUG, "serial", "Read %02X", retVal); + goto exit; + + case 0xB3: + check_serial_data(); + + if (ws_ioRam[0xB3] & 0x80) + { + retVal = (ws_ioRam[0xB3] & ~1) | serial_have_data | 0x04; + } + else + { + retVal = 0x00; + } + + Log(TLOG_DEBUG, "serial", "<<<>>>RS232STA: %02X [%c%c%cxx%c%c%c]", value, (value & 0x80) ? 'E' : 'd', (value & 0x40) ? '3' : '9', + (value & 0x20) ? 'R' : 'n', (value & 0x04) ? 'E' : 'f', (value & 0x02) ? 'V' : 'n', + (value & 0x01) ? 'D' : 'e'); + + /* Serial status: 7 = Enable, 6 = baudrate, 5 = Overrun reset + 2 = Send Buffer empty + 1 = Overrun + 0 = Data Received + */ + serial_speed = ((value & 040) == 0x00) ? BDR_9600 : BDR_38400; + + if ((value & 0x80) == 0x80) + { + open_serial(); + set_baudrate(serial_speed); + check_serial_data(); + } + + break; + } +} + +void rs232_init() +{ + +} \ No newline at end of file diff --git a/source/peripherals/rtc.c b/source/peripherals/rtc.c new file mode 100644 index 0000000..f490f31 --- /dev/null +++ b/source/peripherals/rtc.c @@ -0,0 +1,94 @@ +/* + * NewOswan + * rtc.c: + * + * Created by Manoël Trapier on 19/12/2021. + * Copyright (c) 2014-2021 986-Studio. All rights reserved. + * + */ + +#include + +static int rtcDataRegisterReadCount = 0; + +uint8_t rtc_io_read(void *pdata, uint8_t port) +{ + case (port) + { + case 0xca : // RTC Command and status register + // set ack to always 1 + retVal = (ws_ioRam[0xca] | 0x80); + goto exit; + + case 0xcb : // RTC data register + + if (ws_ioRam[0xca] == 0x15) // get time command + { + struct tm *newtime; + time_t long_time; + time(&long_time); + newtime = localtime(&long_time); + +#define BCD(value) ((value/10)<<4)|(value%10) + + switch (rtcDataRegisterReadCount) + { + case 0: + rtcDataRegisterReadCount++; + retVal = BCD(newtime->tm_year - 100); + goto exit; + + case 1: + rtcDataRegisterReadCount++; + retVal = BCD(newtime->tm_mon); + goto exit; + + case 2: + rtcDataRegisterReadCount++; + retVal = BCD(newtime->tm_mday); + goto exit; + + case 3: + rtcDataRegisterReadCount++; + retVal = BCD(newtime->tm_wday); + goto exit; + + case 4: + rtcDataRegisterReadCount++; + retVal = BCD(newtime->tm_hour); + goto exit; + + case 5: + rtcDataRegisterReadCount++; + retVal = BCD(newtime->tm_min); + goto exit; + + case 6: + rtcDataRegisterReadCount = 0; + retVal = BCD(newtime->tm_sec); + goto exit; + } + + return 0; + } + else + { + // set ack + retVal = (ws_ioRam[0xcb] | 0x80); + goto exit; + } + } +} + +void rtc_io_write(void *pdata, uint8_t port, uint8_t value) +{ + switch(port) + { + case 0xca: + if (value == 0x15) + { + rtcDataRegisterReadCount = 0; + } + break; + } +} \ No newline at end of file diff --git a/source/peripherals/universal_luxor.c b/source/peripherals/universal_luxor.c new file mode 100644 index 0000000..97c3a42 --- /dev/null +++ b/source/peripherals/universal_luxor.c @@ -0,0 +1,9 @@ +/* + * NewOswan + * universal_luxor.c: Implement a "universal" version of both known version of Luxor (Bandai 2001 and Bandai 2003) + * as there is no way from the ROM to really know which version is on the original cart. + * Created by Manoël Trapier on 19/12/2021. + * Copyright (c) 2014-2021 986-Studio. All rights reserved. + * + */ + diff --git a/source/rom.c b/source/rom.c index 5315969..087fbbd 100644 --- a/source/rom.c +++ b/source/rom.c @@ -24,8 +24,8 @@ #include #include #include -#include "log.h" -#include "rom.h" +#include +#include //////////////////////////////////////////////////////////////////////////////// // diff --git a/source/ws.c b/source/ws.c index f1a5d73..a58381b 100644 --- a/source/ws.c +++ b/source/ws.c @@ -27,15 +27,15 @@ #include #include #include -#include "log.h" -#include "rom.h" -#include "./nec/nec.h" -#include "./nec/necintrf.h" -#include "memory.h" -#include "gpu.h" -#include "io.h" -#include "audio.h" -#include "ws.h" +#include +#include +#include "nec.h" +#include "necintrf.h" +#include +#include +#include +#include +#include //////////////////////////////////////////////////////////////////////////////// //