DraCo misc updates, some Casablanca updates.

This commit is contained in:
Toni Wilen 2024-01-22 18:49:50 +02:00
parent 250aaf8feb
commit 90eed80115
5 changed files with 333 additions and 145 deletions

View File

@ -14579,7 +14579,7 @@ void custom_reset(bool hardreset, bool keyboardreset)
maxhpos_short = maxhpos;
updateextblk();
if (currprefs.cs_compatible == CP_DRACO) {
if (currprefs.cs_compatible == CP_DRACO || currprefs.cs_compatible == CP_CASABLANCA) {
// fake draco interrupts
INTENA(0x8000 | 0x4000 | 0x1000 | 0x2000 | 0x0080 | 0x0010 | 0x0008 | 0x0001);
}

434
draco.cpp
View File

@ -37,6 +37,23 @@ static int maxcnt = 100;
.asciz "buserr" | 7: nmi: bus timeout
*/
// CASABLANCA
// INTENA : 0x02000043
// INTPEN : 0x02000083
// INTFRC : 0x020000c3
// ? : 0x02000143
// SuperIO : 0x02400000 (PC-style serial, parallel, WD floppy)
// Interrupt
// Bit 0: Master enable / Soft INT1
// Bit 1: INT4
// Bit 2: INT2
// Bit 3: INT6
// Bit 4: INT1
// Bit 5:
// Bit 6: INT5 (SuperIO)
// DRACO
// INTENA : 0x01000001
// INTPEN : 0x01400001
// INTFRC : 0x01800001
@ -51,15 +68,13 @@ static int maxcnt = 100;
// Interrupt
// Bit 0: Master enable / INT1
// Bit 0: Master enable / Soft INT1
// Bit 1: INT4 (SCSI)
// Bit 2: INT2 (Timer)
// Bit 3: INT6
// SVGA vblank: INT3
// SuperIO: INT5
// IO:
// IO_control : 01
@ -165,6 +180,44 @@ static int draco_scsi_intpen, draco_serial_intpen;
static bool draco_have_vmotion = false;
static void casa_irq(void)
{
uae_u16 irq = 0;
if (draco_scsi_intpen) {
draco_intpen |= 2;
} else {
draco_intpen &= ~2;
}
if (draco_intena & 1) {
uae_u16 mask = draco_intena & draco_intpen;
if (mask) {
if (mask & 1) { // INT1
irq |= 1;
}
if (mask & 2) { // INT4
irq |= 0x80;
}
if (mask & 4) { // INT2
irq |= 8;
}
if (mask & 8) { // INT6
irq |= 0x2000;
}
}
if (draco_intfrc & 1) {
irq |= 1; // software interrupt
}
if (draco_svga_irq_state) {
irq |= 0x0010; // INT3
}
}
INTREQ_f(0x7fff);
if (irq) {
INTREQ_f(0x8000 | irq);
doint();
}
}
static void draco_irq(void)
{
uae_u16 irq = 0;
@ -210,13 +263,22 @@ static void draco_irq(void)
INTREQ_f(0x8000 | irq);
doint();
}
}
static void dc_irq(void)
{
if (currprefs.cs_compatible == CP_DRACO) {
draco_irq();
}
if (currprefs.cs_compatible == CP_CASABLANCA) {
casa_irq();
}
}
void draco_svga_irq(bool state)
{
draco_svga_irq_state = state;
draco_irq();
dc_irq();
}
static uae_u8 draco_kbd_state;
@ -733,8 +795,87 @@ static uaecptr draco_convert_cia_addr(uaecptr addr)
void draco_bustimeout(uaecptr addr)
{
write_log("draco bus timeout %08x\n", addr);
draco_reg[3] |= DRSTAT_BUSTIMO;
write_log("draco bus timeout %08x PC=%08x\n", addr, M68K_GETPC);
if (currprefs.cs_compatible == CP_DRACO) {
draco_reg[3] |= DRSTAT_BUSTIMO;
} else {
draco_reg[2] |= 0x80;
}
}
static const uae_u8 casa_video_config20[] = { 0x00, 0xce, 0x17, 0x47, 0x54, 0x1f, 0x28, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04 };
static uae_u8 casa_video_bget(uaecptr addr)
{
uae_u8 v = 0;
if (addr < 0x28000000) {
if (addr & 3) {
draco_bustimeout(addr);
} else {
int reg = (addr >> 2) & 15;
v = casa_video_config20[reg];
}
} else {
if ((addr & 3) != 3) {
draco_bustimeout(addr);
}
}
return v;
}
static uae_u8 casa_read_io(uaecptr addr)
{
int reg = ((addr & 0xfc0) >> 6) & 0x1f;
uae_u8 v = draco_reg[reg];
switch(reg)
{
case 0x02:
if (draco_reg[0] & 1) {
//v |= 0x80;
}
break;
// casablanca revision
case 0x1f: // 0x7c3
v = draco_revision;
break;
}
return v;
}
static uae_u8 draco_read_io(uaecptr addr)
{
// io
int reg = addr & 0x1f;
uae_u8 v = draco_reg[reg];
switch (reg)
{
case 3:
draco_keyboard_read();
draco_1wire_read();
v = draco_reg[reg];
break;
case 5:
#if KBD_DEBUG > 1
write_log("draco keyboard scan code read %02x\n", v);
#endif
draco_reg[3] &= ~DRSTAT_KBDRECV;
break;
case 9:
v = draco_revision;
draco_timer_latched = true;
break;
case 0xb:
v = (draco_timer_latched ? draco_timer_latch : draco_timer) >> 8;
break;
case 0xd:
v = (draco_timer_latched ? draco_timer_latch : draco_timer) >> 0;
draco_timer_latched = false;
break;
case 0x1d:
v = draco_floppy_get_data();
break;
}
return v;
}
static uae_u32 REGPARAM2 draco_bget(uaecptr addr)
@ -742,7 +883,9 @@ static uae_u32 REGPARAM2 draco_bget(uaecptr addr)
uae_u8 v = 0;
if (maxcnt >= 0) {
write_log(_T("draco_bget %08x %08x\n"), addr, M68K_GETPC);
if (addr != 0x020007c3) {
write_log(_T("draco_bget %08x %08x\n"), addr, M68K_GETPC);
}
maxcnt--;
}
@ -756,8 +899,12 @@ static uae_u32 REGPARAM2 draco_bget(uaecptr addr)
}
if (addr >= 0x20000000) {
draco_bustimeout(addr);
return 0;
if (currprefs.cs_compatible == CP_CASABLANCA) {
v = casa_video_bget(addr);
} else {
draco_bustimeout(addr);
}
return v;
}
if ((addr & 0x07c00000) == 0x04000000) {
@ -830,41 +977,12 @@ static uae_u32 REGPARAM2 draco_bget(uaecptr addr)
} else if ((addr & 0x07c00000) == 0x02000000) {
// io
int reg = addr & 0x1f;
v = draco_reg[reg];
switch(reg)
{
case 3:
draco_keyboard_read();
draco_1wire_read();
v = draco_reg[reg];
break;
case 5:
#if KBD_DEBUG > 1
write_log("draco keyboard scan code read %02x\n", v);
#endif
break;
case 9:
v = draco_revision;
draco_timer_latched = true;
break;
case 0xb:
v = (draco_timer_latched ? draco_timer_latch : draco_timer) >> 8;
break;
case 0xd:
v = (draco_timer_latched ? draco_timer_latch : draco_timer) >> 0;
draco_timer_latched = false;
break;
case 0x1d:
v = draco_floppy_get_data();
break;
if (currprefs.cs_compatible == CP_DRACO) {
v = draco_read_io(addr);
} else {
v = casa_read_io(addr);
}
// casablanca revision
if (addr == 0x020007c3)
v = draco_revision;
} else if ((addr & 0x07c00000) == 0x02800000) {
// CIA (no CIAs if rev4+)
@ -966,7 +1084,7 @@ static void REGPARAM2 draco_lput(uaecptr addr, uae_u32 l)
cpuboard_ncr710_io_bput(reg + 1, l >> 16);
cpuboard_ncr710_io_bput(reg + 0, l >> 24);
} else {
} else if (addr < 0x28000000) {
write_log(_T("draco_lput %08x %08x %08x\n"), addr, l, M68K_GETPC);
}
@ -976,6 +1094,81 @@ static void REGPARAM2 draco_wput(uaecptr addr, uae_u32 w)
write_log(_T("draco_wput %08x %04x %08x\n"), addr, w & 0xffff, M68K_GETPC);
}
static void casa_write_io(uaecptr addr, uae_u8 b)
{
int reg = ((addr & 0xfc0) >> 6) & 0x1f;
draco_reg[reg] = b;
switch (reg)
{
case 1:
draco_intena = b & 63;
casa_irq();
break;
case 2:
draco_intpen = b & 63;
casa_irq();
break;
case 3:
draco_intfrc = b & 63;
casa_irq();
break;
case 4:
casa_irq();
break;
}
}
static void draco_write_io(uaecptr addr, uae_u8 b)
{
int reg = addr & 0x1f;
uae_u8 oldval = draco_reg[reg];
draco_reg[reg] = b;
//write_log(_T("draco_bput %08x %02x %08x\n"), addr, b & 0xff, M68K_GETPC);
switch (reg)
{
case 1:
if (b & DRCNTRL_WDOGDAT) {
draco_watchdog = 0;
}
draco_irq();
draco_keyboard_write(b);
break;
case 3: // RO
draco_reg[reg] = oldval;
break;
case 7:
draco_irq();
break;
case 9:
draco_reg[7] &= ~DRSTAT2_TMRIRQPEN;
break;
case 0x0b:
draco_timer &= 0x00ff;
draco_timer |= b << 8;
break;
case 0x0d:
draco_timer &= 0xff00;
draco_timer |= b;
break;
case 0x11:
draco_1wire_send(0);
break;
case 0x13:
draco_1wire_send(1);
break;
case 0x15:
draco_1wire_reset();
break;
case 0x17:
draco_keyboard_done();
break;
case 0x19:
draco_reg[3] &= ~DRSTAT_BUSTIMO;
break;
}
}
static void REGPARAM2 draco_bput(uaecptr addr, uae_u32 b)
{
if (maxcnt >= 0) {
@ -983,13 +1176,14 @@ static void REGPARAM2 draco_bput(uaecptr addr, uae_u32 b)
write_log(_T("draco_bput %08x %02x %08x\n"), addr, b & 0xff, M68K_GETPC);
}
if (addr >= 0x28000000 && addr < 0x30000000 && draco_have_vmotion) {
vmotion_write(addr & 0x07ffffff, b);
return;
}
if (addr >= 0x20000000) {
draco_bustimeout(addr);
if (currprefs.cs_compatible == CP_DRACO) {
if (addr >= 0x28000000 && addr < 0x30000000 && draco_have_vmotion) {
vmotion_write(addr & 0x07ffffff, b);
return;
}
draco_bustimeout(addr);
}
return;
}
@ -1076,54 +1270,10 @@ static void REGPARAM2 draco_bput(uaecptr addr, uae_u32 b)
} else if ((addr & 0x07c00000) == 0x02000000) {
// IO
int reg = addr & 0x1f;
uae_u8 oldval = draco_reg[reg];
draco_reg[reg] = b;
//write_log(_T("draco_bput %08x %02x %08x\n"), addr, b & 0xff, M68K_GETPC);
switch(reg)
{
case 1:
if (b & DRCNTRL_WDOGDAT) {
draco_watchdog = 0;
}
draco_irq();
draco_keyboard_write(b);
break;
case 3: // RO
draco_reg[reg] = oldval;
break;
case 7:
draco_irq();
break;
case 9:
draco_reg[7] &= ~DRSTAT2_TMRIRQPEN;
break;
case 0x0b:
draco_timer &= 0x00ff;
draco_timer |= b << 8;
break;
case 0x0d:
draco_timer &= 0xff00;
draco_timer |= b;
break;
case 0x11:
draco_1wire_send(0);
break;
case 0x13:
draco_1wire_send(1);
break;
case 0x15:
draco_1wire_reset();
break;
case 0x17:
draco_keyboard_done();
break;
case 0x19:
draco_reg[3] &= ~DRSTAT_BUSTIMO;
break;
if (currprefs.cs_compatible == CP_DRACO) {
draco_write_io(addr, b);
} else {
casa_write_io(addr, b);
}
} else if ((addr & 0x07000000) == 0x01000000) {
@ -1187,7 +1337,6 @@ static addrbank draco_bank = {
draco_lget, draco_wget, ABFLAG_IO, S_READ, S_WRITE
};
void draco_ext_interrupt(bool i6)
{
if (i6) {
@ -1195,7 +1344,7 @@ void draco_ext_interrupt(bool i6)
} else {
draco_intpen |= 4;
}
draco_irq();
dc_irq();
}
void draco_keycode(uae_u16 scancode, uae_u8 state)
@ -1214,48 +1363,63 @@ static void draco_hsync(void)
uae_u16 tm = 5, ot;
static int hcnt;
ot = draco_timer;
draco_timer -= tm;
if ((draco_timer > 0xf000 && ot < 0x1000) || (draco_timer < 0x1000 && ot > 0xf000)) {
draco_reg[7] |= DRSTAT2_TMRIRQPEN;
if (draco_reg[7] & DRSTAT2_TMRINTENA) {
draco_irq();
#if 0
if (currprefs.cs_compatible == CP_CASABLANCA) {
static int casa_timer;
casa_timer++;
if (casa_timer >= maxvpos) {
draco_svga_irq(true);
} else {
draco_svga_irq(false);
}
}
#endif
if (currprefs.cs_compatible == CP_DRACO) {
ot = draco_timer;
draco_timer -= tm;
if ((draco_timer > 0xf000 && ot < 0x1000) || (draco_timer < 0x1000 && ot > 0xf000)) {
draco_reg[7] |= DRSTAT2_TMRIRQPEN;
if (draco_reg[7] & DRSTAT2_TMRINTENA) {
draco_irq();
}
}
if (draco_kbd_buffer_len > 0) {
draco_keyboard_send();
}
if (draco_kbd_buffer_len == 0 && draco_kbd_in_buffer_len > 0 && !(draco_reg[3] & DRSTAT_KBDRECV)) {
uae_u8 code = (uae_u8)draco_kbd_in_buffer[0];
uae_u8 state = (draco_kbd_in_buffer[0] & 0x8000) ? 1 : 0;
for (int i = 1; i < draco_kbd_in_buffer_len; i++) {
draco_kbd_in_buffer[i - i] = draco_kbd_in_buffer[i];
}
draco_kbd_in_buffer_len--;
draco_key_process(code, state);
}
hcnt++;
if (hcnt >= 60) {
draco_1wire_rtc_count();
hcnt = 0;
}
draco_watchdog++;
if (0 && draco_watchdog > 312 * 50) {
IRQ_forced(7, -1);
activate_debugger();
draco_watchdog = 0;
}
}
x86_floppy_run();
if (draco_kbd_buffer_len > 0) {
draco_keyboard_send();
}
if (draco_kbd_buffer_len == 0 && draco_kbd_in_buffer_len > 0 && !(draco_reg[3] & DRSTAT_KBDRECV)) {
uae_u8 code = (uae_u8)draco_kbd_in_buffer[0];
uae_u8 state = (draco_kbd_in_buffer[0] & 0x8000) ? 1 : 0;
for (int i = 1; i < draco_kbd_in_buffer_len; i++) {
draco_kbd_in_buffer[i - i] = draco_kbd_in_buffer[i];
}
draco_kbd_in_buffer_len--;
draco_key_process(code, state);
}
hcnt++;
if (hcnt >= 60) {
draco_1wire_rtc_count();
hcnt = 0;
}
draco_watchdog++;
if (0 && draco_watchdog > 312 * 50) {
IRQ_forced(7, -1);
activate_debugger();
draco_watchdog = 0;
}
}
void draco_set_scsi_irq(int id, int level)
{
draco_scsi_intpen = level;
draco_irq();
dc_irq();
}
@ -1266,7 +1430,7 @@ static void x86_irq(int irq, bool state)
} else {
draco_fdc_intpen = state;
}
draco_irq();
dc_irq();
}
void draco_free(void)
@ -1371,6 +1535,7 @@ void draco_init(void)
if (currprefs.cs_compatible == CP_CASABLANCA) {
draco_revision = 9;
draco_cias = 3;
draco_reset(1);
device_add_rethink(draco_irq);
@ -1399,6 +1564,7 @@ void casablanca_map_overlay(void)
// KS ROM is here
map_banks(&kickmem_bank, 0x02c00000 >> 16, 524288 >> 16, 0);
map_banks(&draco_bank, 0x03000000 >> 16, 0x01000000 >> 16, 0);
map_banks(&draco_bank, 0x20000000 >> 16, 0x20000000 >> 16, 0);
}

View File

@ -4489,7 +4489,10 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
}
aci->parent = aci;
if (!aci->doinit) {
if (gb->rbc->rtgmem_type == GFXBOARD_ID_VGA) {
if (gb->rbc->rtgmem_type == GFXBOARD_ID_ALTAIS_Z3) {
aci->start = 0x20000000;
aci->size = 0x1000000;
} else if (gb->rbc->rtgmem_type == GFXBOARD_ID_VGA) {
static const int parent[] = { ROMTYPE_A1060, ROMTYPE_A2088, ROMTYPE_A2088T, ROMTYPE_A2286, ROMTYPE_A2386, 0 };
aci->parent_romtype = parent;
} else if (gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {

View File

@ -4218,6 +4218,23 @@ static void do_trace(void)
}
}
static void int_request_do(bool i6)
{
if (i6) {
if (currprefs.cs_compatible == CP_DRACO || currprefs.cs_compatible == CP_CASABLANCA) {
draco_ext_interrupt(true);
} else {
INTREQ_f(0x8000 | 0x2000);
}
} else {
if (currprefs.cs_compatible == CP_DRACO || currprefs.cs_compatible == CP_CASABLANCA) {
draco_ext_interrupt(false);
} else {
INTREQ_f(0x8000 | 0x0008);
}
}
}
static void check_uae_int_request(void)
{
bool irq2 = false;
@ -4227,14 +4244,14 @@ static void check_uae_int_request(void)
if (!irq2 && uae_interrupts2[i]) {
uae_atomic v = atomic_and(&uae_interrupts2[i], 0);
if (v) {
INTREQ_f(0x8000 | 0x0008);
int_request_do(false);
irq2 = true;
}
}
if (!irq6 && uae_interrupts6[i]) {
uae_atomic v = atomic_and(&uae_interrupts6[i], 0);
if (v) {
INTREQ_f(0x8000 | 0x2000);
int_request_do(true);
irq6 = true;
}
}
@ -4242,11 +4259,11 @@ static void check_uae_int_request(void)
}
if (uae_int_requested) {
if (!irq2 && (uae_int_requested & 0x00ff)) {
INTREQ_f(0x8000 | 0x0008);
int_request_do(false);
irq2 = true;
}
if (!irq6 && (uae_int_requested & 0xff00)) {
INTREQ_f(0x8000 | 0x2000);
int_request_do(true);
irq6 = true;
}
if (uae_int_requested & 0xff0000) {
@ -4276,7 +4293,7 @@ void safe_interrupt_set(int num, int id, bool i6)
atomic_or(p, 1 << id);
atomic_or(&uae_interrupt, 1);
} else {
if (currprefs.cs_compatible == CP_DRACO) {
if (currprefs.cs_compatible == CP_DRACO || currprefs.cs_compatible == CP_CASABLANCA) {
draco_ext_interrupt(i6);
} else {
int inum = i6 ? 13 : 3;

10
x86.cpp
View File

@ -787,11 +787,13 @@ static void floppy_format(struct x86_bridge *xb, bool real)
uae_u8 cx = 0, hx = 0, rx = 0, nx = 0;
if (floppy_specify_pio) {
if (real) {
cx = *pioptr++;
hx = *pioptr++;
rx = *pioptr++;
nx = *pioptr++;
floppy_pio_cnt += 4;
if (floppy_pio_cnt <= floppy_pio_len) {
cx = *pioptr++;
hx = *pioptr++;
rx = *pioptr++;
nx = *pioptr++;
}
} else {
floppy_pio_len += 4;
}