Godzil 4d345079ae Fix building
Most patches are temporary and there just to let the code to build. It will not work in the current state.
Also now force the use of paged memory. It was not working properly because of the way the old GPU code is working.
2022-06-27 16:59:11 +01:00

395 lines
9.0 KiB
C

/*******************************************************************************
* NewOswan
* ws.c: Base wonderswan implementation
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <log.h>
#include <rom.h>
#include "nec.h"
#include "necintrf.h"
#include <memory.h>
#include <gpu.h>
#include <io.h>
#include <audio.h>
#include <ws.h>
uint32_t ws_cycles;
uint32_t ws_skip;
uint32_t ws_cyclesByLine = 0;
uint32_t vblank_count = 0;
char *ws_sram_path = NULL;
char *ws_ieep_path = NULL;
char *ws_rom_path = NULL;
wssystem_t systemType;
void ws_patchRom(void)
{
uint8_t *rom = memory_getRom();
uint32_t romSize = memory_getRomSize();
Log(TLOG_DEBUG, "ws", "developper Id: 0x%.2x", rom[romSize - 10]);
Log(TLOG_DEBUG, "ws", "Game Id: 0x%.2x", rom[romSize - 8]);
if (!ws_cyclesByLine)
{
ws_cyclesByLine = 256;
}
}
int ws_init(char *rompath)
{
uint8_t *rom;
uint32_t romSize;
if ((rom = ws_rom_load(rompath, &romSize)) == NULL)
{
Log(TLOG_PANIC, "ws", "Error: cannot load %s", rompath);
return (0);
}
ws_staticRam = (uint8_t *)load_file(ws_sram_path);
if (ws_staticRam == NULL)
{
ws_staticRam = (uint8_t *)create_file(ws_sram_path, 0x10000);
}
if (ws_staticRam == NULL)
{
Log(TLOG_PANIC, "ws", "Card SRAM load error!\n");
return 0;
}
externalEeprom = (uint8_t *)load_file(ws_ieep_path);
if (externalEeprom == NULL)
{
externalEeprom = (uint8_t *)create_file(ws_ieep_path, 0x100000);
}
if (externalEeprom == NULL)
{
Log(TLOG_PANIC, "ws", "Card EEPROM load error!\n");
return 0;
}
ws_memory_init(rom, romSize);
ws_patchRom();
io_init();
ws_audio_init();
ws_gpu_init();
if (ws_rotated())
{
io_flipControls();
}
return (1);
}
void ws_reset(void)
{
ws_memory_reset();
io_reset();
ws_audio_reset();
ws_gpu_reset();
nec_reset(NULL);
nec_set_reg(NEC_SP, 0x2000);
}
int ws_executeLine(int16_t *framebuffer, int renderLine)
{
int drawWholeScreen = 0;
ws_audio_process();
// update scanline register
//ws_ioRam[2] = ws_gpu_scanline;
/* Why twice like that and random cycle count???? */
ws_cycles = nec_execute((ws_cyclesByLine >> 1) + (rand() & 7));
ws_cycles += nec_execute((ws_cyclesByLine >> 1) + (rand() & 7));
if (ws_cycles >= ws_cyclesByLine + ws_cyclesByLine)
{
ws_skip = ws_cycles / ws_cyclesByLine;
}
else
{
ws_skip = 1;
}
ws_cycles %= ws_cyclesByLine;
for (uint32_t uI = 0 ; uI < ws_skip ; uI++)
{
if (renderLine)
{
ws_gpu_renderScanline(framebuffer);
}
ws_gpu_scanline++;
if (ws_gpu_scanline == 144)
{
drawWholeScreen = 1;
}
}
if (ws_gpu_scanline > 158)
{
ws_gpu_scanline = 0;
{
#if 0
if ((ws_ioRam[0xb2] & 32)) /* VBLANK Timer */
{
/* TODO: REPAIR THAT SHIT */
ws_ioRam[0xb6] &= ~32;
nec_int((ws_ioRam[0xb0] + 5) * 4);
}
#endif
}
}
#if 0
ws_ioRam[2] = ws_gpu_scanline;
#endif
if (drawWholeScreen)
{
#if 0
if (ws_ioRam[0xb2] & 64) /* VBLANK INT */
{
ws_ioRam[0xb6] &= ~64;
nec_int((ws_ioRam[0xb0] + 6) * 4);
}
#endif
vblank_count++;
}
#if 0
if (ws_ioRam[0xa4] && (ws_ioRam[0xb2] & 128)) /*HBLANK TMR*/
{
/* TODO: Check that shit */
if (!ws_ioRam[0xa5])
{
ws_ioRam[0xa5] = ws_ioRam[0xa4];
}
if (ws_ioRam[0xa5])
{
ws_ioRam[0xa5]--;
}
if ((!ws_ioRam[0xa5]) && (ws_ioRam[0xb2] & 128))
{
ws_ioRam[0xb6] &= ~128;
nec_int((ws_ioRam[0xb0] + 7) * 4);
}
}
if ((ws_ioRam[0x2] == ws_ioRam[0x3]) && (ws_ioRam[0xb2] & 16)) /*SCANLINE INT*/
{
ws_ioRam[0xb6] &= ~16;
nec_int((ws_ioRam[0xb0] + 4) * 4);
}
#endif
return (drawWholeScreen);
}
void ws_done(void)
{
ws_memory_done();
io_done();
ws_audio_done();
ws_gpu_done();
}
void ws_set_system(wssystem_t system)
{
if (system == WS_SYSTEM_AUTODETECT)
{
system = WS_SYSTEM_CRYSTAL;
}
systemType = system;
}
wssystem_t ws_get_system()
{
return systemType;
}
#define MacroLoadNecRegisterFromFile(F, R) \
read(fp,&value,sizeof(value)); \
nec_set_reg(R,value);
int ws_loadState(char *statepath)
{
// TODO: need a complete rewrite
#if 0
Log(TLOG_NORMAL, "ws", "loading %s\n", statepath);
uint16_t crc = memory_getRomCrc();
uint16_t newCrc;
unsigned value;
uint8_t ws_newVideoMode;
int fp = open(statepath, O_RDONLY);
if (fp == -1)
{
return (0);
}
read(fp, &newCrc, 2);
if (newCrc != crc)
{
return (-1);
}
MacroLoadNecRegisterFromFile(fp, NEC_IP);
MacroLoadNecRegisterFromFile(fp, NEC_AW);
MacroLoadNecRegisterFromFile(fp, NEC_BW);
MacroLoadNecRegisterFromFile(fp, NEC_CW);
MacroLoadNecRegisterFromFile(fp, NEC_DW);
MacroLoadNecRegisterFromFile(fp, NEC_CS);
MacroLoadNecRegisterFromFile(fp, NEC_DS);
MacroLoadNecRegisterFromFile(fp, NEC_ES);
MacroLoadNecRegisterFromFile(fp, NEC_SS);
MacroLoadNecRegisterFromFile(fp, NEC_IX);
MacroLoadNecRegisterFromFile(fp, NEC_IY);
MacroLoadNecRegisterFromFile(fp, NEC_BP);
MacroLoadNecRegisterFromFile(fp, NEC_SP);
MacroLoadNecRegisterFromFile(fp, NEC_FLAGS);
MacroLoadNecRegisterFromFile(fp, NEC_VECTOR);
MacroLoadNecRegisterFromFile(fp, NEC_PENDING);
MacroLoadNecRegisterFromFile(fp, NEC_NMI_STATE);
MacroLoadNecRegisterFromFile(fp, NEC_IRQ_STATE);
read(fp, internalRam, 65536);
read(fp, ws_staticRam, 65536);
read(fp, ws_ioRam, 256);
read(fp, ws_paletteColors, 8);
read(fp, ws_palette, 16 * 4 * 2);
read(fp, wsc_palette, 16 * 16 * 2);
read(fp, &ws_newVideoMode, 1);
read(fp, &ws_gpu_scanline, 1);
read(fp, externalEeprom, 131072);
ws_audio_readState(fp);
close(fp);
// force a video mode change to make all tiles dirty
ws_gpu_clearCache();
#endif
return (1);
}
#define MacroStoreNecRegisterToFile(F, R) \
value=nec_get_reg(R); \
write(fp,&value,sizeof(value));
int ws_saveState(char *statepath)
{
// TODO: need a complete rewrite
#if 0
uint16_t crc = memory_getRomCrc();
uint32_t value;
char newPath[1024];
Log(TLOG_DEBUG, "ws", "saving %s\n", statepath);
if (strlen(statepath) < 4)
{
sprintf(newPath, "%s.wss", statepath);
}
else
{
int len = strlen(statepath);
if ((statepath[len - 1] != 's') && (statepath[len - 1] != 'S'))
{
sprintf(newPath, "%s.wss", statepath);
}
else if ((statepath[len - 2] != 's') && (statepath[len - 2] != 'S'))
{
sprintf(newPath, "%s.wss", statepath);
}
else if ((statepath[len - 3] != 'w') && (statepath[len - 3] != 'w'))
{
sprintf(newPath, "%s.wss", statepath);
}
else if (statepath[len - 4] != '.')
{
sprintf(newPath, "%s.wss", statepath);
}
else
{
sprintf(newPath, "%s", statepath);
}
}
int fp = open(newPath, O_RDWR | O_CREAT, 0644);
if (fp == -1)
{
return (0);
}
write(fp, &crc, 2);
MacroStoreNecRegisterToFile(fp, NEC_IP);
MacroStoreNecRegisterToFile(fp, NEC_AW);
MacroStoreNecRegisterToFile(fp, NEC_BW);
MacroStoreNecRegisterToFile(fp, NEC_CW);
MacroStoreNecRegisterToFile(fp, NEC_DW);
MacroStoreNecRegisterToFile(fp, NEC_CS);
MacroStoreNecRegisterToFile(fp, NEC_DS);
MacroStoreNecRegisterToFile(fp, NEC_ES);
MacroStoreNecRegisterToFile(fp, NEC_SS);
MacroStoreNecRegisterToFile(fp, NEC_IX);
MacroStoreNecRegisterToFile(fp, NEC_IY);
MacroStoreNecRegisterToFile(fp, NEC_BP);
MacroStoreNecRegisterToFile(fp, NEC_SP);
MacroStoreNecRegisterToFile(fp, NEC_FLAGS);
MacroStoreNecRegisterToFile(fp, NEC_VECTOR);
MacroStoreNecRegisterToFile(fp, NEC_PENDING);
MacroStoreNecRegisterToFile(fp, NEC_NMI_STATE);
MacroStoreNecRegisterToFile(fp, NEC_IRQ_STATE);
write(fp, internalRam, 65536);
write(fp, ws_staticRam, 65536);
write(fp, ws_ioRam, 256);
write(fp, ws_paletteColors, 8);
write(fp, ws_palette, 16 * 4 * 2);
write(fp, wsc_palette, 16 * 16 * 2);
write(fp, &ws_videoMode, 1);
write(fp, &ws_gpu_scanline, 1);
write(fp, externalEeprom, 131072);
ws_audio_writeState(fp);
close(fp);
#endif
return (1);
}
int ws_rotated(void)
{
uint8_t *rom = memory_getRom();
uint32_t romSize = memory_getRomSize();
return (rom[romSize - 4] & 1);
}