Starting a rewrite of how the IO works.
Currently 100% broken, also going to change how devices are selected for each system so no more if/else everywhere and system should be more accurate.
This commit is contained in:
9
source/peripherals/buttons.c
Normal file
9
source/peripherals/buttons.c
Normal file
@@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
9
source/peripherals/color_system.c
Normal file
9
source/peripherals/color_system.c
Normal file
@@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
36
source/peripherals/debug.c
Normal file
36
source/peripherals/debug.c
Normal file
@@ -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 <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
9
source/peripherals/dma.c
Normal file
9
source/peripherals/dma.c
Normal file
@@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
336
source/peripherals/eeprom.c
Normal file
336
source/peripherals/eeprom.c
Normal file
@@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory.h>
|
||||
#include <nec.h>
|
||||
#include <log.h>
|
||||
#include <gpu.h>
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
9
source/peripherals/mono_system.c
Normal file
9
source/peripherals/mono_system.c
Normal file
@@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
230
source/peripherals/rs232.c
Normal file
230
source/peripherals/rs232.c
Normal file
@@ -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 <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <unistd.h> /* UNIX standard function definitions */
|
||||
#include <errno.h> /* Error number definitions */
|
||||
#include <termios.h> /* POSIX terminal control definitions */
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <nec.h>
|
||||
#include <log.h>
|
||||
|
||||
/* 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]", retVal, (retVal & 0x80) ? 'E' : 'd',
|
||||
(retVal & 0x40) ? '3' : '9', (retVal & 0x20) ? 'R' : 'n', (retVal & 0x04) ? 'E' : 'f',
|
||||
(retVal & 0x02) ? 'V' : 'n', (retVal & 0x01) ? 'D' : 'e');
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void rs232_io_write(void *pdata, uint8_t port, uint8_t value)
|
||||
{
|
||||
switch(port)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void rs232_init()
|
||||
{
|
||||
|
||||
}
|
||||
94
source/peripherals/rtc.c
Normal file
94
source/peripherals/rtc.c
Normal file
@@ -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 <stdint.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
9
source/peripherals/universal_luxor.c
Normal file
9
source/peripherals/universal_luxor.c
Normal file
@@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user