Added emulation of Packard Bell PB410A, along with the built-in Headland HT216-32 video.
This commit is contained in:
parent
cc4118fca0
commit
35962551dd
18 changed files with 1178 additions and 13 deletions
122
src/acc3221.c
Normal file
122
src/acc3221.c
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#include "ibm.h"
|
||||
#include "acc3221.h"
|
||||
#include "fdc.h"
|
||||
#include "ide.h"
|
||||
#include "io.h"
|
||||
#include "lpt.h"
|
||||
#include "serial.h"
|
||||
|
||||
static struct
|
||||
{
|
||||
int reg_idx;
|
||||
uint8_t regs[256];
|
||||
} acc3221;
|
||||
|
||||
#define REG_BE_LPT1_DISABLE (1 << 4)
|
||||
|
||||
#define REG_DB_SERIAL1_DISABLE (1 << 4)
|
||||
#define REG_DB_SERIAL2_DISABLE (1 << 1)
|
||||
|
||||
#define REG_DE_SIRQ3_SOURCE (3 << 6)
|
||||
#define REG_DE_SIRQ3_SERIAL1 (1 << 6)
|
||||
#define REG_DE_SIRQ3_SERIAL2 (3 << 6)
|
||||
|
||||
#define REG_DE_SIRQ4_SOURCE (3 << 4)
|
||||
#define REG_DE_SIRQ4_SERIAL1 (1 << 4)
|
||||
#define REG_DE_SIRQ4_SERIAL2 (3 << 4)
|
||||
|
||||
#define REG_FB_FDC_DISABLE (1 << 1)
|
||||
|
||||
#define REG_FE_IDE_DISABLE (1 << 1)
|
||||
|
||||
static void acc3221_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
if (!(addr & 1))
|
||||
acc3221.reg_idx = val;
|
||||
else
|
||||
{
|
||||
acc3221.regs[acc3221.reg_idx] = val;
|
||||
// pclog("Write ACC2036 R%02x %02x %04x:%04x %i\n", acc2036.reg_idx, val, CS,cpu_state.pc, ins);
|
||||
|
||||
if (acc3221.reg_idx >= 0xbc)
|
||||
{
|
||||
// pclog("Write ACC3221 R%02x %02x %04x:%04x %i\n", acc3221.reg_idx, val, CS,cpu_state.pc, ins);
|
||||
fdc_remove();
|
||||
if (!(acc3221.regs[0xfb] & REG_FB_FDC_DISABLE))
|
||||
fdc_add();
|
||||
|
||||
serial1_remove();
|
||||
if (!(acc3221.regs[0xdb] & REG_DB_SERIAL1_DISABLE))
|
||||
{
|
||||
uint16_t addr = (acc3221.regs[0xdc] & 0x7f) << 2;
|
||||
|
||||
if ((acc3221.regs[0xde] & REG_DE_SIRQ3_SOURCE) == REG_DE_SIRQ3_SERIAL1)
|
||||
{
|
||||
// pclog("COM1 addr %03x IRQ 3\n", addr);
|
||||
serial1_set(addr, 3);
|
||||
}
|
||||
else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ3_SERIAL1)
|
||||
{
|
||||
// pclog("COM1 addr %03x IRQ 4\n", addr);
|
||||
serial1_set(addr, 4);
|
||||
}
|
||||
// else
|
||||
// pclog("COM1 addr %03x no IRQ\n", addr);
|
||||
}
|
||||
// else
|
||||
// pclog("COM1 disabled\n");
|
||||
|
||||
serial2_remove();
|
||||
if (!(acc3221.regs[0xdb] & REG_DB_SERIAL2_DISABLE))
|
||||
{
|
||||
uint16_t addr = (acc3221.regs[0xdd] & 0x7f) << 2;
|
||||
|
||||
if ((acc3221.regs[0xde] & REG_DE_SIRQ3_SOURCE) == REG_DE_SIRQ3_SERIAL2)
|
||||
{
|
||||
// pclog("COM2 addr %03x IRQ 3\n", addr);
|
||||
serial2_set(addr, 3);
|
||||
}
|
||||
else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ3_SERIAL2)
|
||||
{
|
||||
// pclog("COM2 addr %03x IRQ 4\n", addr);
|
||||
serial2_set(addr, 4);
|
||||
}
|
||||
// else
|
||||
// pclog("COM2 addr %03x no IRQ\n", addr);
|
||||
}
|
||||
// else
|
||||
// pclog("COM2 disabled\n");
|
||||
|
||||
lpt1_remove();
|
||||
lpt2_remove();
|
||||
if (!(acc3221.regs[0xbe] & REG_BE_LPT1_DISABLE))
|
||||
{
|
||||
// pclog("LPT1 addr %03x\n", acc3221.regs[0xbf] << 2);
|
||||
lpt1_init(acc3221.regs[0xbf] << 2);
|
||||
}
|
||||
// else
|
||||
// pclog("LPT1 disabled\n");
|
||||
|
||||
ide_pri_disable();
|
||||
if (!(acc3221.regs[0xfe] & REG_FE_IDE_DISABLE))
|
||||
ide_pri_enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t acc3221_read(uint16_t addr, void *p)
|
||||
{
|
||||
if (!(addr & 1))
|
||||
return acc3221.reg_idx;
|
||||
|
||||
if (acc3221.reg_idx < 0xbc)
|
||||
return 0xff;
|
||||
|
||||
return acc3221.regs[acc3221.reg_idx];
|
||||
}
|
||||
|
||||
void acc3221_init()
|
||||
{
|
||||
memset(&acc3221, 0, sizeof(acc3221));
|
||||
io_sethandler(0x00f2, 0x0002, acc3221_read, NULL, NULL, acc3221_write, NULL, NULL, NULL);
|
||||
}
|
||||
Loading…
Reference in a new issue