Partial MacroSystem DraCo emulation

This commit is contained in:
Toni Wilen 2024-01-01 18:45:49 +02:00
parent f49194fc83
commit 5f51bec663
22 changed files with 1334 additions and 162 deletions

View File

@ -1,128 +0,0 @@
#include "sysconfig.h"
#include "sysdeps.h"
#include "options.h"
#include "uae.h"
#include "memory.h"
#include "newcpu.h"
#include "casablanca.h"
/*
53C710 (SCSI)
Base: 0x04000000
IRQ: 4
INTREQ: 7 (AUD0)
DracoMotion
Base: 0x20000000
IRQ: 3
INTREQ: 4 (COPER)
Size: 128k
Autoconfig: 83 17 30 00 47 54 00 00 00 00 00 00 00 00 00 00 (18260/23)
Mouse
Base: 0x02400BE3
IRQ: 4
INTREQ: 9 (AUD2)
Serial
Base: 0x02400FE3
IRQ: 4
INTREQ: 10 (AUD3)
Floppy:
Base: 0x02400003
IRQ: 5
INTREQ: 11 (RBF)
*/
static uae_u32 REGPARAM2 casa_lget(uaecptr addr)
{
static int max = 100;
if (max < 0) {
write_log(_T("casa_lget %08x %08x\n"), addr, M68K_GETPC);
max--;
}
return 0;
}
static uae_u32 REGPARAM2 casa_wget(uaecptr addr)
{
static int max = 100;
if (max >= 0) {
write_log(_T("casa_wget %08x %08x\n"), addr, M68K_GETPC);
max--;
}
return 0;
}
static uae_u32 REGPARAM2 casa_bget(uaecptr addr)
{
uae_u8 v = 0;
static int max = 100;
if (max >= 0) {
write_log(_T("casa_bget %08x %08x\n"), addr, M68K_GETPC);
max--;
}
// casa
if (addr == 0x020007c3)
v = 4;
// draco
if (addr == 0x02000009)
v = 4;
return v;
}
static void REGPARAM2 casa_lput(uaecptr addr, uae_u32 l)
{
static int max = 100;
if (max < 0)
return;
max--;
write_log(_T("casa_lput %08x %08x %08x\n"), addr, l, M68K_GETPC);
}
static void REGPARAM2 casa_wput(uaecptr addr, uae_u32 w)
{
static int max = 100;
if (max < 0)
return;
max--;
write_log(_T("casa_wput %08x %04x %08x\n"), addr, w & 0xffff, M68K_GETPC);
}
static void REGPARAM2 casa_bput(uaecptr addr, uae_u32 b)
{
static int max = 100;
if (max < 0)
return;
max--;
write_log(_T("casa_bput %08x %02x %08x\n"), addr, b & 0xff, M68K_GETPC);
}
static addrbank casa_ram_bank = {
casa_lget, casa_wget, casa_bget,
casa_lput, casa_wput, casa_bput,
default_xlate, default_check, NULL, NULL, _T("Casablanca IO"),
dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE,
};
void casablanca_map_overlay(void)
{
// Casablanca has ROM at address zero, no chip ram, no overlay.
map_banks(&kickmem_bank, 524288 >> 16, 524288 >> 16, 0);
map_banks(&extendedkickmem_bank, 0 >> 16, 524288 >> 16, 0);
map_banks(&casa_ram_bank, 0x02000000 >> 16, 0x01000000 >> 16, 0);
// at least draco has rom here
map_banks(&kickmem_bank, 0x02c00000 >> 16, 524288 >> 16, 0);
}

View File

@ -9457,7 +9457,7 @@ static int bip_casablanca(struct uae_prefs *p, int config, int compa, int romche
case 2:
p->cpu_model = 68060;
p->fpu_model = 68060;
p->mmu_model = 68040;
p->mmu_model = 68060;
break;
}
p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
@ -9472,6 +9472,30 @@ static int bip_casablanca(struct uae_prefs *p, int config, int compa, int romche
return configure_rom(p, roms, romcheck);
}
static int bip_draco(struct uae_prefs *p, int config, int compa, int romcheck)
{
int roms[8];
roms[0] = 16;
roms[1] = -1;
p->bogomem.size = 0;
p->chipmem.size = 0x200000;
p->cpu_model = 68060;
p->fpu_model = 68060;
p->mmu_model = 68060;
p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
p->cpu_compatible = p->address_space_24 = 0;
p->m68k_speed = -1;
p->immediate_blits = 0;
p->produce_sound = 2;
p->floppyslots[0].dfxtype = DRV_NONE;
p->floppyslots[1].dfxtype = DRV_NONE;
p->cs_compatible = CP_DRACO;
built_in_chipset_prefs(p);
return configure_rom(p, roms, romcheck);
}
int built_in_prefs (struct uae_prefs *p, int model, int config, int compa, int romcheck)
{
int v = 0;
@ -9521,6 +9545,9 @@ int built_in_prefs (struct uae_prefs *p, int model, int config, int compa, int r
case 13:
v = bip_super (p, config, compa, romcheck);
break;
case 14:
v = bip_draco(p, config, compa, romcheck);
break;
}
if ((p->cpu_model >= 68020 || !p->cpu_memory_cycle_exact) && !p->immediate_blits)
p->waiting_blits = 1;

View File

@ -14551,6 +14551,11 @@ void custom_reset(bool hardreset, bool keyboardreset)
maxhpos = ntsc ? MAXHPOS_NTSC : MAXHPOS_PAL;
maxhpos_short = maxhpos;
updateextblk();
if (currprefs.cs_compatible == CP_DRACO) {
// fake draco interrupts
INTENA(0x8000 | 0x4000 | 0x1000 | 0x2000 | 0x0080 | 0x0010 | 0x0008 | 0x0001);
}
}
specialmonitor_reset();

View File

@ -63,6 +63,7 @@
#ifdef RETROPLATFORM
#include "rp.h"
#endif
#include "draco.h"
#include "dsp3210/dsp_glue.h"
#define MAX_DEVICE_ITEMS 64
@ -351,7 +352,9 @@ void virtualdevice_free(void)
#endif
ethernet_enumerate_free();
rtarea_free();
#ifdef WITH_DRACO
draco_reset();
#endif
execute_device_items(device_leaves, device_leave_cnt);
}
@ -410,6 +413,9 @@ void virtualdevice_init (void)
#ifdef WITH_TABLETLIBRARY
tabletlib_install ();
#endif
#ifdef WITH_DRACO
draco_init();
#endif
}
void devices_restore_start(void)

992
draco.cpp Normal file
View File

@ -0,0 +1,992 @@
/* MacroSystem DraCo
*
* Toni Wilen 2023-2024
*/
#include "sysconfig.h"
#include "sysdeps.h"
#include "options.h"
#include "uae.h"
#include "memory.h"
#include "newcpu.h"
#include "devices.h"
#include "custom.h"
#include "debug.h"
#include "x86.h"
#include "ncr_scsi.h"
#include "draco.h"
#include "zfile.h"
static int maxcnt = 100;
/*
.asciz "kbd/soft" | 1: native keyboard, soft ints
.asciz "cia/zbus" | 2: cia, PORTS
.asciz "lclbus" | 3: local bus, e.g. Altais vbl
.asciz "drscsi" | 4: mainboard scsi
.asciz "superio" | 5: superio chip
.asciz "lcl/zbus" | 6: lcl/zorro lev6
.asciz "buserr" | 7: nmi: bus timeout
*/
// INTENA : 0x01000001
// INTPEN : 0x01400001
// INTFRC : 0x01800001
// ? : 0x01c00001
// IO : 0x02000000 (Misc control, 1-wire RTC)
// SuperIO : 0x02400000 (PC-style serial, parallel, WD floppy) PC IO = Amiga address >> 2
// CIA : 0x02800000 (only in pre-4 revisions)
// KS ROM : 0x02c00000 (A3000 KS 3.1)
// Z2 : 0x03e80000
// SCSI : 0x04000000 (53C710)
// SVGA : 0x20000000 (NCR 77C32BLT)
// Interrupt
// Bit 0: Master enable / INT1
// Bit 1: INT4 (SCSI)
// Bit 2: INT2 (Timer)
// Bit 3: INT6
// SVGA vblank: INT3
// SuperIO: INT5
// IO:
// IO_control : 01
#define DRCNTRL_FDCINTENA 1
#define DRCNTRL_KBDDATOUT 2
#define DRCNTRL_KBDCLKOUT 4
#define DRCNTRL_WDOGDIS 8
#define DRCNTRL_WDOGDAT 16
#define DRCNTRL_KBDINTENA 32
#define DRCNTRL_KBDKBDACK 64
#define DRCNTRL_SCSITERM 128
// IO_status : 03
#define DRSTAT_CLKDAT 1 // (1-wire data)
#define DRSTAT_KBDDATIN 2
#define DRSTAT_KBDCLKIN 4
#define DRSTAT_KBDRECV 8
#define DRSTAT_CLKBUSY 16 // (1-wire, busy)
#define DRSTAT_BUSTIMO 32
#define DRSTAT_SCSILED 64
// IO_KBD_data : 05
// IO_status2 : 07
#define DRSTAT2_KBDBUSY 1
#define DRSTAT2_PARIRQPEN 4
#define DRSTAT2_PARIRQENA 8
#define DRSTAT2_TMRINTENA 16
#define DRSTAT2_TMRIRQPEN 32
// Revision : 09 (write=timer reset)
// IO_TimerHI : 0B
// IO_TimerLO : 0D
// unused : 0F
// IO_clockw0 : 11 (1-wire, write 1)
// IO_clockw1 : 13 (1-wire, write 0)
// IO_clockrst : 15 (1-wire, reset)
// IO_KBD_Reset : 17
// IO_bustimeout: 19
// IO_scsiledres: 1b
// IO_fdcread : 1d
// IO_parrst : 1f
/*
53C710 (SCSI)
Base: 0x04000000
IRQ: 4
INTREQ: 7 (AUD0)
DracoMotion
Base: 0x20000000
IRQ: 3
INTREQ: 4 (COPER)
Size: 128k
Autoconfig: 83 17 30 00 47 54 00 00 00 00 00 00 00 00 00 00 (18260/23)
Mouse
Base: 0x02400BE3
IRQ: 4
INTREQ: 9 (AUD2)
Serial
Base: 0x02400FE3
IRQ: 4
INTREQ: 10 (AUD3)
Floppy:
Base: 0x02400003
IRQ: 5
INTREQ: 11 (RBF)
*/
void serial_reset();
void serial_write(uint16_t addr, uint8_t val, void *p);
uint8_t serial_read(uint16_t addr, void *p);
void draco_serial_init(void **s1, void **s2);
static void *draco_serial[2];
static uae_u8 draco_intena, draco_intpen, draco_svga_irq_state;
static uae_u16 draco_timer, draco_timer_latch;
static bool draco_timer_latched;
static bool draco_fdc_intpen;
static uae_u8 draco_superio_cfg[16];
static uae_s8 draco_superio_idx;
static uae_u8 draco_reg[0x20];
static void draco_irq(void)
{
uae_u16 irq = 0;
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_svga_irq_state) {
irq |= 0x0010; // INT3
}
if (draco_fdc_intpen && (draco_reg[1] & DRCNTRL_FDCINTENA)) {
irq = 0x1000; // INT5
}
if ((draco_reg[7] & DRSTAT2_TMRINTENA) && (draco_reg[7] & DRSTAT2_TMRIRQPEN)) {
irq |= 1;
}
if ((draco_reg[3] & DRSTAT_KBDRECV) && (draco_reg[1] & DRCNTRL_KBDINTENA)) {
irq |= 1;
}
}
INTREQ_f(0x7fff);
if (irq) {
INTREQ_f(0x8000 | irq);
doint();
}
}
void draco_svga_irq(bool state)
{
draco_svga_irq_state = state;
draco_irq();
}
static uae_u8 draco_kbd_state, draco_kbd_state2;
static uae_u16 draco_kbd_code;
static int draco_kbd_poll;
static uae_u8 draco_kbd_buffer[10];
static uae_u8 draco_kbd_buffer_len;
static uae_u8 draco_keyboard_read(uae_u8 v)
{
if (draco_kbd_state2) {
draco_reg[3] &= ~DRSTAT_KBDCLKIN;
draco_kbd_poll++;
if (draco_kbd_state2 > 0 && draco_kbd_poll >= 4) {
draco_reg[3] |= DRSTAT_KBDCLKIN;
draco_kbd_code >>= 1;
draco_kbd_code |= (draco_reg[1] & DRCNTRL_KBDDATOUT) ? 0x8000 : 0;
draco_kbd_state2++;
draco_kbd_poll = 0;
}
}
return v;
}
static void draco_keyboard_write(uae_u8 v)
{
v &= DRCNTRL_KBDDATOUT | DRCNTRL_KBDCLKOUT;
if (v == draco_kbd_state) {
return;
}
// start receive
if ((v & DRCNTRL_KBDCLKOUT) && !(draco_kbd_state & DRCNTRL_KBDCLKOUT)) {
draco_reg[3] |= DRSTAT_KBDCLKIN;
draco_kbd_code = 0;
draco_kbd_state2 = 1;
draco_kbd_poll = 0;
}
draco_kbd_state = v;
}
static void draco_keyboard_done(void)
{
if (draco_kbd_state2 == 12) {
draco_kbd_code >>= 5;
draco_kbd_code &= 0xff;
write_log("draco received keyboard data %04x\n", draco_kbd_code);
if (draco_kbd_code == 0xf2) {
draco_kbd_buffer[0] = 0xab;
draco_kbd_buffer[1] = 0x83;
draco_kbd_buffer_len = 2;
}
}
draco_reg[3] &= ~DRSTAT_KBDCLKIN;
draco_reg[3] &= ~DRSTAT_KBDRECV;
draco_kbd_state2 = 0;
draco_kbd_poll = 0;
}
static void draco_keyboard_send(void)
{
if (draco_kbd_buffer_len <= 0) {
return;
}
if (!(draco_reg[3] & DRSTAT_KBDRECV)) {
draco_kbd_buffer_len--;
uae_u8 code = draco_kbd_buffer[draco_kbd_buffer_len];
draco_reg[5] = code;
draco_reg[3] |= DRSTAT_KBDRECV;
draco_irq();
}
}
static uae_u8 draco_1wire_data[40], draco_1wire_state, draco_1wire_dir;
static uae_u8 draco_1wire_sram[512 + 32], draco_1wire_scratchpad[32 + 3], draco_1wire_rom[8];
static uae_u8 draco_1wire_cmd, draco_1wire_bytes, draco_1wire_dat;
static uae_s16 draco_1wire_sram_offset, draco_1wire_sram_offset_copy;
static uae_s8 draco_1wire_rom_offset, draco_1wire_cnt, draco_1wire_busycnt;
static bool draco_1wire_bit;
#define DS_ROM_MATCH 0x55
#define DS_ROM_SEARCH 0xf0
#define DS_ROM_SKIP 0xcc
#define DS_ROM_READ 0x33
#define DS_WRITE_SCRATCHPAD 0x0f
#define DS_READ_SCRATCHPAD 0xaa
#define DS_COPY_SCRATCHPAD 0x55
static void draco_1wire_rtc_count(void)
{
uae_u8 *rtc = draco_1wire_sram + 512;
rtc[2]++;
if (rtc[2] == 0) {
rtc[3]++;
if (rtc[3] == 0) {
rtc[4]++;
if (rtc[4] == 0) {
rtc[5]++;
}
}
}
}
static void draco_1wire_rtc_validate(void)
{
uae_u8 *rtc = draco_1wire_sram + 512;
rtc[0] &= ~7;
draco_1wire_rtc_count();
}
static void draco_1wire_set_bit(void)
{
uae_u8 *dptr = NULL;
int maxlen = 0;
if (draco_1wire_cmd == DS_ROM_SEARCH) {
dptr = draco_1wire_sram;
maxlen = sizeof(draco_1wire_sram);
} else if (draco_1wire_cmd == DS_READ_SCRATCHPAD) {
dptr = draco_1wire_scratchpad;
maxlen = sizeof(draco_1wire_scratchpad);
}
if (dptr && draco_1wire_sram_offset >= 0 && draco_1wire_dir) {
if (draco_1wire_rom_offset >= 0) {
draco_1wire_dat = draco_1wire_rom[draco_1wire_rom_offset];
uae_u8 bit = (draco_1wire_rom[draco_1wire_rom_offset] >> draco_1wire_cnt) & 1;
draco_1wire_bit = bit != 0;
} else {
if (draco_1wire_sram_offset >= maxlen) {
draco_1wire_dat = 0xff;
draco_1wire_bit = true;
} else {
if (draco_1wire_sram_offset >= 0) {
draco_1wire_dat = dptr[draco_1wire_sram_offset];
uae_u8 bit = (dptr[draco_1wire_sram_offset] >> draco_1wire_cnt) & 1;
draco_1wire_bit = bit != 0;
}
}
}
}
}
static uae_u8 draco_1wire_read(uae_u8 v)
{
if (draco_1wire_bit) {
draco_reg[3] |= DRSTAT_CLKDAT;
v |= DRSTAT_CLKDAT;
} else {
draco_reg[3] &= ~DRSTAT_CLKDAT;
v &= ~DRSTAT_CLKDAT;
}
if (draco_1wire_cnt == 8 && !(draco_reg[3] & DRSTAT_CLKBUSY)) {
write_log("draco read 1-wire SRAM byte %02x, %02x\n", draco_1wire_dat, draco_1wire_bytes);
draco_1wire_cnt = 0;
draco_1wire_bytes++;
if (draco_1wire_rom_offset >= 0) {
if (draco_1wire_rom_offset == sizeof(draco_1wire_rom)) {
draco_1wire_rom_offset = -1;
}
} else if (draco_1wire_cmd == DS_READ_SCRATCHPAD) {
if (draco_1wire_sram_offset == 2) {
draco_1wire_sram_offset = (draco_1wire_sram_offset_copy & 31) + 3;
} else if (draco_1wire_sram_offset < 2) {
draco_1wire_sram_offset++;
} else {
draco_1wire_sram_offset++;
draco_1wire_sram_offset -= 3;
draco_1wire_sram_offset &= 31;
draco_1wire_sram_offset += 3;
}
} else {
draco_1wire_sram_offset++;
}
}
if (draco_reg[3] & DRSTAT_CLKBUSY) {
draco_1wire_busycnt--;
if (draco_1wire_busycnt < 0) {
draco_reg[3] &= ~DRSTAT_CLKBUSY;
}
}
return v;
}
static void draco_1wire_busy(void)
{
draco_reg[3] |= DRSTAT_CLKBUSY;
draco_1wire_busycnt = 3;
}
static void draco_1wire_send(int bit)
{
if (draco_1wire_dir) {
draco_1wire_set_bit();
draco_1wire_cnt++;
draco_1wire_busy();
}
if (!draco_1wire_dir) {
draco_1wire_data[0] >>= 1;
draco_1wire_data[0] |= bit ? 0x80 : 0;
draco_1wire_cnt++;
draco_1wire_busy();
}
if (draco_1wire_cnt == 8 && !draco_1wire_dir) {
bool gotcmd = false;
if (!draco_1wire_state) {
draco_1wire_cmd = draco_1wire_data[0];
if (draco_1wire_cmd != DS_ROM_SKIP) {
draco_1wire_state = 1;
gotcmd = true;
} else {
draco_1wire_rom_offset = -1;
}
}
for (int i = sizeof(draco_1wire_data) - 1; i >= 1; i--) {
draco_1wire_data[i] = draco_1wire_data[i - 1];
}
write_log("draco received 1-wire byte %02x, cnt %02x\n", draco_1wire_data[0], draco_1wire_bytes);
draco_1wire_cnt = 0;
draco_1wire_bytes++;
// read data command + 2 address bytes?
if (draco_1wire_cmd == DS_ROM_SEARCH && draco_1wire_data[3] == DS_ROM_SEARCH) {
draco_1wire_sram_offset = (draco_1wire_data[1] << 8) | draco_1wire_data[2];
draco_1wire_dir = 1;
draco_1wire_bytes = 0;
write_log("draco received 1-wire SRAM read command, offset %04x\n", draco_1wire_sram_offset);
}
// write scratchpad + 2 address bytes?
if (draco_1wire_cmd == DS_WRITE_SCRATCHPAD && draco_1wire_data[3] == DS_WRITE_SCRATCHPAD) {
draco_1wire_sram_offset = (draco_1wire_data[1] << 8) | draco_1wire_data[2];
draco_1wire_sram_offset_copy = draco_1wire_sram_offset;
memset(draco_1wire_scratchpad, 0, sizeof(draco_1wire_scratchpad));
write_log("draco received 1-wire SRAM scratchpad write command, offset %04x\n", draco_1wire_sram_offset);
}
// read scratchpad
if (draco_1wire_cmd == DS_READ_SCRATCHPAD) {
draco_1wire_sram_offset = 0;
draco_1wire_dir = 1;
draco_1wire_bytes = 0;
draco_1wire_set_bit();
write_log("draco received 1-wire SRAM scratchpad read command\n");
}
// copy scratchpad
if (draco_1wire_cmd == DS_COPY_SCRATCHPAD && draco_1wire_data[4] == DS_COPY_SCRATCHPAD) {
draco_1wire_sram_offset = 0;
uae_u8 status = draco_1wire_data[1];
if (status == draco_1wire_scratchpad[2] &&
draco_1wire_data[2] == draco_1wire_scratchpad[1] &&
draco_1wire_data[3] == draco_1wire_scratchpad[0]) {
int start = draco_1wire_sram_offset_copy & 31;
int offset = draco_1wire_sram_offset_copy & ~31;
write_log("draco received 1-wire SRAM scratchpad copy command, accepted\n");
for (int i = 0; i < 32; i++) {
draco_1wire_sram[offset + start] = draco_1wire_scratchpad[start + 3];
write_log("draco 1-wire SRAM scratchpad copy %02x -> %04x\n", draco_1wire_sram[offset + start], offset + start);
if (start == (draco_1wire_scratchpad[2] & 31)) {
break;
}
start++;
start &= 31;
}
draco_1wire_scratchpad[0] |= 0x80;
draco_1wire_rtc_validate();
draco_1wire_busy();
draco_1wire_bit = 0;
} else {
write_log("draco received 1-wire SRAM scratchpad copy command, rejected\n");
draco_1wire_busy();
}
}
}
}
static void draco_1wire_reset(void)
{
if (draco_1wire_state) {
// write scratchpad
if (draco_1wire_cmd == DS_WRITE_SCRATCHPAD) {
int len = draco_1wire_bytes - 4;
int start = draco_1wire_sram_offset_copy;
for (int i = 0; i < len; i++) {
draco_1wire_scratchpad[(start & 31) + 3] = draco_1wire_data[len - i];
start++;
start &= 31;
}
draco_1wire_scratchpad[0] = draco_1wire_sram_offset_copy >> 0;
draco_1wire_scratchpad[1] = draco_1wire_sram_offset_copy >> 8;
draco_1wire_scratchpad[2] = (start - 1) & 31;
if (len > 32) {
draco_1wire_scratchpad[2] |= 0x40;
} else if (len < 32) {
draco_1wire_scratchpad[2] |= 0x20;
}
write_log("draco received 1-wire SRAM scratchpad write, %d bytes received\n", len);
}
}
memset(draco_1wire_data, 0, sizeof(draco_1wire_data));
draco_1wire_cnt = 0;
draco_1wire_state = 0;
draco_1wire_dir = 0;
draco_1wire_bytes = 0;
draco_1wire_sram_offset = -1;
draco_1wire_rom_offset = 0;
write_log("draco 1-wire reset\n");
}
static uae_u32 REGPARAM2 draco_lget(uaecptr addr)
{
uae_u32 l = 0;
if ((addr & 0x07c00000) == 0x04000000) {
write_log("draco scsi lput %08x %08x\n", addr, l);
int reg = addr & 0xffff;
l = cpuboard_ncr710_io_bget(reg + 0) << 24;
l |= cpuboard_ncr710_io_bget(reg + 1) << 16;
l |= cpuboard_ncr710_io_bget(reg + 2) << 8;
l |= cpuboard_ncr710_io_bget(reg + 3) << 0;
} else {
write_log(_T("draco_lget %08x %08x\n"), addr, M68K_GETPC);
}
return l;
}
static uae_u32 REGPARAM2 draco_wget(uaecptr addr)
{
write_log(_T("draco_wget %08x %08x\n"), addr, M68K_GETPC);
return 0;
}
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);
maxcnt--;
}
if (addr >= 0x20000000) {
write_log("draco bus timeout %08x\n", addr);
draco_reg[3] |= DRSTAT_BUSTIMO;
return 0;
}
if ((addr & 0x07c00000) == 0x04000000) {
int reg = addr & 0xffff;
v = cpuboard_ncr710_io_bget(reg);
write_log("draco scsi read %08x\n", addr);
} else if ((addr & 0x07c00000) == 0x02400000) {
// super io
int reg = (addr & 0x7fff) >> 2;
switch(reg)
{
case 0x3f0:
if (draco_superio_idx >= 0) {
v = draco_superio_idx;
} else {
v = x86_infloppy(reg);
}
break;
case 0x3f1:
if (draco_superio_idx >= 0 && draco_superio_idx < 16) {
v = draco_superio_cfg[draco_superio_idx];
} else {
v = x86_infloppy(reg);
}
break;
case 0x3f2:
case 0x3f3:
case 0x3f4:
case 0x3f5:
case 0x3f7:
v = x86_infloppy(reg);
break;
case 0x3f8:
case 0x3f9:
case 0x3fa:
case 0x3fb:
case 0x3fc:
case 0x3fd:
case 0x3fe:
case 0x3ff:
v = serial_read(reg, draco_serial[0]);
break;
case 0x2f8:
case 0x2f9:
case 0x2fa:
case 0x2fb:
case 0x2fc:
case 0x2fd:
case 0x2fe:
case 0x2ff:
v = serial_read(reg, draco_serial[1]);
break;
default:
write_log("draco superio read %04x = %02x\n", (addr >> 2) & 0xfff, v);
break;
}
} else if ((addr & 0x07c00000) == 0x02000000) {
// io
if ((addr & 0xffffff) > 0x1f)
write_log("x");
int reg = addr & 0x1f;
v = draco_reg[reg];
switch(reg)
{
case 3:
v = draco_keyboard_read(v);
v = draco_1wire_read(v);
break;
case 9:
v = 4;
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;
}
} else if ((addr & 0x07c00000) == 0x02800000) {
// CIA (no CIAs if rev4+)
} else if ((addr & 0x07000000) == 0x01000000) {
// interrupt control
int reg = (addr & 0x0c00001);
switch(reg)
{
case 0x000001:
v = draco_intena;
break;
case 0x400001:
v = draco_intpen;
break;
case 0x800001:
v = 0;
break;
case 0xc0001:
v = 0;
break;
}
} else {
write_log("draco unknown bank read %08x\n", addr);
}
return v;
}
static void REGPARAM2 draco_lput(uaecptr addr, uae_u32 l)
{
if ((addr & 0x07c00000) == 0x04000000) {
write_log("draco scsi lput %08x %08x\n", addr, l);
int reg = addr & 0xffff;
cpuboard_ncr710_io_bput(reg + 0, l >> 24);
cpuboard_ncr710_io_bput(reg + 1, l >> 16);
cpuboard_ncr710_io_bput(reg + 2, l >> 8);
cpuboard_ncr710_io_bput(reg + 3, l >> 0);
} else {
write_log(_T("draco_lput %08x %08x %08x\n"), addr, l, M68K_GETPC);
}
}
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 REGPARAM2 draco_bput(uaecptr addr, uae_u32 b)
{
if (maxcnt >= 0) {
maxcnt--;
write_log(_T("draco_bput %08x %02x %08x\n"), addr, b & 0xff, M68K_GETPC);
}
if (addr >= 0x20000000) {
draco_reg[3] |= DRSTAT_BUSTIMO;
return;
}
if ((addr & 0x07c00000) == 0x04000000) {
write_log("draco scsi put %08x\n", addr);
int reg = addr & 0xffff;
cpuboard_ncr710_io_bput(reg, b);
} else if ((addr & 0x07c00000) == 0x02400000) {
// super io
int reg = (addr & 0x7fff) >> 2;
switch (reg)
{
case 0x3f0:
if (b == 0x55 && draco_superio_idx < 0) {
draco_superio_idx++;
} else if (b == 0xaa && draco_superio_idx >= 0) {
draco_superio_idx = -2;
} else if (draco_superio_idx >= 0) {
draco_superio_idx = b;
} else {
x86_outfloppy(reg, b);
}
break;
case 0x3f1:
if (draco_superio_idx >= 0 && draco_superio_idx < 16) {
draco_superio_cfg[draco_superio_idx] = b;
} else {
x86_outfloppy(reg, b);
}
break;
case 0x3f2:
case 0x3f3:
case 0x3f4:
case 0x3f5:
case 0x3f7:
x86_outfloppy(reg, b);
draco_superio_idx = -2;
break;
case 0x3f8:
case 0x3f9:
case 0x3fa:
case 0x3fb:
case 0x3fc:
case 0x3fd:
case 0x3fe:
case 0x3ff:
serial_write(reg, b, draco_serial[0]);
break;
case 0x2f8:
case 0x2f9:
case 0x2fa:
case 0x2fb:
case 0x2fc:
case 0x2fd:
case 0x2fe:
case 0x2ff:
serial_write(reg, b, draco_serial[1]);
break;
default:
write_log("draco superio write %04x = %02x\n", (addr >> 2) & 0xfff, b);
break;
}
} else if ((addr & 0x07c00000) == 0x02800000) {
// CIA (no CIAs if rev4+)
} else if ((addr & 0x07c00000) == 0x02000000) {
// IO
int reg = addr & 0x1f;
uae_u8 oldval = draco_reg[reg];
draco_reg[reg] = b;
//draco_reg[1] |= DRCNTRL_FDCINTENA;
//write_log(_T("draco_bput %08x %02x %08x\n"), addr, b & 0xff, M68K_GETPC);
switch(reg)
{
case 1:
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;
}
} else if ((addr & 0x07000000) == 0x01000000) {
// interrupt control
int reg = (addr & 0x0c00001);
switch (reg)
{
case 0x000001:
draco_intena = b & 15;
draco_irq();
break;
case 0x400001:
draco_intpen = b & 15;
if (b)
write_log("draco interrupt 0x400001 write %02x\n", b);
draco_irq();
break;
case 0x800001:
if (b)
write_log("draco interrupt 0x800001 write %02x\n", b);
draco_intpen |= b & 15;
draco_irq();
break;
case 0xc00001:
if (b)
write_log("draco interrupt 0xc00001 write %02x\n", b);
draco_irq();
break;
}
} else {
write_log("draco unknown bank write %08x\n", addr);
}
}
static addrbank draco_bank = {
draco_lget, draco_wget, draco_bget,
draco_lput, draco_wput, draco_bput,
default_xlate, default_check, NULL, NULL, _T("DraCo mainboard"),
dummy_lgeti, dummy_wgeti, ABFLAG_IO, S_READ, S_WRITE
};
void casablanca_map_overlay(void)
{
// Casablanca has ROM at address zero, no chip ram, no overlay.
map_banks(&kickmem_bank, 524288 >> 16, 524288 >> 16, 0);
map_banks(&extendedkickmem_bank, 0 >> 16, 524288 >> 16, 0);
map_banks(&draco_bank, 0x02000000 >> 16, 0x01000000 >> 16, 0);
// KS ROM is here
map_banks(&kickmem_bank, 0x02c00000 >> 16, 524288 >> 16, 0);
map_banks(&draco_bank, 0x03000000 >> 16, 0x01000000 >> 16, 0);
}
static void draco_hsync(void)
{
uae_u16 tm = 1, 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();
}
}
x86_floppy_run();
if (draco_kbd_buffer_len > 0) {
draco_keyboard_send();
}
hcnt++;
if (hcnt >= 60) {
draco_1wire_rtc_count();
hcnt = 0;
}
}
void draco_set_scsi_irq(int id, int level)
{
if (level) {
draco_intpen |= 2;
} else {
draco_intpen &= ~2;
}
draco_irq();
}
static void x86_irq(int irq, bool state)
{
draco_fdc_intpen = state;
draco_irq();
}
void draco_reset(void)
{
TCHAR path[MAX_DPATH];
cfgfile_resolve_path_out_load(currprefs.flashfile, path, MAX_DPATH, PATH_ROM);
struct zfile *draco_flashfile = zfile_fopen(path, _T("wb"), ZFD_NORMAL);
if (draco_flashfile) {
uae_u8 zeros[8] = { 0 };
zfile_fwrite(draco_1wire_rom, sizeof(draco_1wire_rom), 1, draco_flashfile);
zfile_fwrite(zeros, sizeof(zeros), 1, draco_flashfile);
zfile_fwrite(draco_1wire_sram, sizeof(draco_1wire_sram), 1, draco_flashfile);
zfile_fclose(draco_flashfile);
}
}
void draco_init(void)
{
if (currprefs.cs_compatible != CP_DRACO) {
return;
}
draco_intena = 0;
draco_intpen = 0;
draco_timer = 0;
draco_timer_latched = 0;
draco_timer_latched = false;
draco_svga_irq_state = 0;
draco_fdc_intpen = false;
draco_superio_idx = -2;
draco_kbd_buffer_len = 0;
draco_kbd_state2 = 0;
memset(draco_superio_cfg, 0, sizeof(draco_superio_cfg));
draco_superio_cfg[0] = 0x3b;
draco_superio_cfg[1] = 0x9f;
draco_superio_cfg[2] = 0xdc;
draco_superio_cfg[3] = 0x78;
draco_superio_cfg[6] = 0xff;
draco_superio_cfg[13] = 0x65;
draco_superio_cfg[14] = 1;
memset(draco_reg, 0, sizeof(draco_reg));
draco_1wire_rtc_validate();
draco_1wire_rom[0] = 0x04;
draco_1wire_rom[1] = 1;
draco_1wire_rom[2] = 2;
draco_1wire_rom[3] = 3;
draco_1wire_rom[4] = 4;
draco_1wire_rom[5] = 5;
draco_1wire_rom[6] = 6;
draco_1wire_rom[7] = 0xaa;
TCHAR path[MAX_DPATH];
cfgfile_resolve_path_out_load(currprefs.flashfile, path, MAX_DPATH, PATH_ROM);
struct zfile *draco_flashfile = zfile_fopen(path, _T("rb"), ZFD_NORMAL);
if (draco_flashfile) {
zfile_fread(draco_1wire_rom, sizeof(draco_1wire_rom), 1, draco_flashfile);
zfile_fseek(draco_flashfile, 8, SEEK_CUR);
zfile_fread(draco_1wire_sram, sizeof(draco_1wire_sram), 1, draco_flashfile);
zfile_fclose(draco_flashfile);
}
x86_initfloppy(x86_irq);
draco_serial_init(&draco_serial[0], &draco_serial[1]);
device_add_rethink(draco_irq);
device_add_hsync(draco_hsync);
}
void draco_map_overlay(void)
{
// hide custom registers
map_banks(&dummy_bank, 0xd00000 >> 16, 0x200000 >> 16, 0);
// hide cias
map_banks(&dummy_bank, 0xa00000 >> 16, 0x200000 >> 16, 0);
map_banks(&extendedkickmem_bank, 0 >> 16, 524288 >> 16, 0);
map_banks(&draco_bank, 0x01000000 >> 16, 0x01c00000 >> 16, 0);
map_banks(&kickmem_bank, 0x02c00000 >> 16, 524288 >> 16, 0);
map_banks(&draco_bank, 0x04000000 >> 16, 0x01000000 >> 16, 0);
map_banks(&draco_bank, 0x21000000 >> 16, 0x1f000000 >> 16, 0);
}

View File

@ -3614,6 +3614,17 @@ static void expansion_add_autoconfig(struct uae_prefs *p)
cards_set[cardno++].map = NULL;
}
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
struct rtgboardconfig *rbc = &p->rtgboards[i];
int type = gfxboard_get_configtype(rbc);
if (rbc->rtgmem_size && rbc->rtgmem_type >= GFXBOARD_HARDWARE && type == BOARD_NONAUTOCONFIG_BEFORE) {
cards_set[cardno].flags = 4 | (i << 16);
cards_set[cardno].name = _T("MainBoardRTG");
cards_set[cardno].zorro = BOARD_NONAUTOCONFIG_BEFORE;
cards_set[cardno++].initnum = gfxboard_init_memory;
}
}
// add possible non-autoconfig boards
add_cpu_expansions(p, BOARD_NONAUTOCONFIG_BEFORE, NULL);
add_expansions(p, BOARD_NONAUTOCONFIG_BEFORE, NULL, 0);
@ -3677,7 +3688,8 @@ static void expansion_add_autoconfig(struct uae_prefs *p)
#ifdef GFXBOARD
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
struct rtgboardconfig *rbc = &p->rtgboards[i];
if (rbc->rtgmem_size && rbc->rtgmem_type >= GFXBOARD_HARDWARE && gfxboard_get_configtype(rbc) <= 2) {
int type = gfxboard_get_configtype(rbc);
if (rbc->rtgmem_size && rbc->rtgmem_type >= GFXBOARD_HARDWARE && type <= 2) {
cards_set[cardno].flags = 4 | (i << 16);
if (gfxboard_get_func(rbc)) {
cards_set[cardno].name = _T("Z2RTG");
@ -6869,6 +6881,22 @@ static const struct cpuboardsubtype harms_sub[] = {
}
};
static const struct cpuboardsubtype draco_sub[] = {
{
_T("DraCo"),
_T("draco"),
ROMTYPE_CB_DRACO | ROMTYPE_NONE, 0, 4,
draco_add_scsi_unit, EXPANSIONTYPE_SCSI,
BOARD_MEMORY_HIGHMEM,
128 * 1024 * 1024,
0,
ncr710_draco_init, NULL, BOARD_NONAUTOCONFIG_BEFORE, 1,
},
{
NULL
}
};
static const struct cpuboardsubtype dummy_sub[] = {
{ NULL }
};
@ -6959,6 +6987,11 @@ const struct cpuboardtype cpuboards[] = {
_T("Harms"),
harms_sub, 0
},
{
BOARD_DRACO,
_T("Draco"),
draco_sub, 0
},
{
NULL
}

View File

@ -125,7 +125,7 @@ struct gfxboard
struct gfxboard_func *func;
device_t *pcemdev;
uae_u8 er_flags;
bool pci;
int bustype;
};
#define ISP4() (gb->rbc->rtgmem_type == GFXBOARD_ID_PICASSO4_Z2 || gb->rbc->rtgmem_type == GFXBOARD_ID_PICASSO4_Z3)
@ -249,6 +249,13 @@ static const struct gfxboard boards[] =
0x00000000, 0x00100000, 0x00400000, 0x00400000, 0, 3, 2, false, false,
0, 0, NULL, &ncr_retina_z3_device
},
{
GFXBOARD_ID_ALTAIS_Z3,
_T("Altais [DracoBus]"), _T("MacroSystem"), _T("Altais"),
18260, 19, 0, 0,
0x00000000, 0x00400000, 0x00400000, 0x00400000, 0, 4, 3, false, false,
0, 0, NULL, &ncr_retina_z3_device, 0, GFXBOARD_BUSTYPE_DRACO
},
{
GFXBOARD_ID_HARLEQUIN,
_T("Harlequin [Zorro II]"), _T("ACS"), _T("Harlequin_PAL"),
@ -270,14 +277,14 @@ static const struct gfxboard boards[] =
0, 0, 0, 0,
0x00000000, 0x01000000, 0x01000000, 0x01000000, 0, 0, -1, false, false,
ROMTYPE_VOODOO3,
0, NULL, &voodoo_3_3000_device, 0, true
0, NULL, &voodoo_3_3000_device, 0, GFXBOARD_BUSTYPE_PCI
},
{
GFXBOARD_ID_S3VIRGE_PCI,
_T("Virge [PCI]"), _T("S3"), _T("S3VIRGE_PCI"),
0, 0, 0, 0,
0x00000000, 0x00400000, 0x00400000, 0x10000000, 0, 0, -1, false, false,
0, 0, NULL, &s3_virge_device, 0, true
0, 0, NULL, &s3_virge_device, 0, GFXBOARD_BUSTYPE_PCI
},
{
GFXBOARD_ID_VGA,
@ -784,9 +791,12 @@ static void gfxboard_rethink(void)
{
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
struct rtggfxboard *gb = &rtggfxboards[i];
if (gb->pcemdev && gb->pcemobject && gb->gfxboard_intreq && gb->gfxboard_intena) {
if (gb->pcemdev && gb->pcemobject) {
int irq = 0;
if (gb->board->irq > 0) {
if (gb->board->bustype == GFXBOARD_BUSTYPE_DRACO) {
void draco_svga_irq(bool state);
draco_svga_irq(gb->gfxboard_intreq);
} else if (gb->gfxboard_intreq &&gb->gfxboard_intena) {
if (gb->board->irq == 2 && gb->gfxboard_intena != 6)
irq = 2;
else
@ -892,7 +902,7 @@ static void init_board (struct rtggfxboard *gb)
gb->gfxmem_bank->flags |= ABFLAG_ALLOCINDIRECT | ABFLAG_PPCIOSPACE;
gb->gfxmem_bank->label = _T("*");
mapped_malloc(gb->gfxmem_bank);
} else if (gb->board->pci) {
} else if (gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {
// We don't know VRAM address until PCI bridge and
// PCI display card's BARs have been initialized
;
@ -915,7 +925,7 @@ static void init_board (struct rtggfxboard *gb)
//gb->gfxmem_bank->baseaddr = gb->vram;
// restore original value because this is checked against
// configured size in expansion.cpp
if (!gb->board->pci) {
if (!gb->board->bustype) {
gb->gfxmem_bank->allocated_size = rbc->rtgmem_size;
gb->gfxmem_bank->reserved_size = rbc->rtgmem_size;
}
@ -3628,7 +3638,7 @@ void gfxboard_voodoo_lfb_endianswap(int m)
{
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
struct rtggfxboard *gb = &rtggfxboards[i];
if (gb->active && gb->board->pci) {
if (gb->active && gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {
if (gb->lfbbyteswapmode != m) {
gb->lfbbyteswapmode = m;
if (gb->original_pci_bank) {
@ -3943,7 +3953,7 @@ void gfxboard_s3virge_lfb_endianswap(int m)
{
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
struct rtggfxboard *gb = &rtggfxboards[i];
if (gb->active && gb->board->pci) {
if (gb->active && gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {
gb->lfbbyteswapmode = m;
}
}
@ -3952,7 +3962,7 @@ void gfxboard_s3virge_lfb_endianswap2(int m)
{
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
struct rtggfxboard *gb = &rtggfxboards[i];
if (gb->active && gb->board->pci) {
if (gb->active && gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {
gb->mmiobyteswapmode = m;
}
}
@ -4473,7 +4483,7 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
gb->monswitch_keep_trying = true;
}
}
if (gb->board->pci) {
if (gb->board->bustype > 0) {
aci->zorro = -1;
}
aci->parent = aci;
@ -4481,7 +4491,7 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
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->pci) {
} else if (gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {
static const int parent[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, 0 };
aci->parent_romtype = parent;
} else {
@ -4548,7 +4558,7 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
gb->active = true;
if (gb->board->pci) {
if (gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {
TCHAR path[MAX_DPATH];
fetch_rompath(path, sizeof path / sizeof(TCHAR));
@ -4583,6 +4593,28 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
gb->gfxboard_intena = 1;
return true;
}
if (gb->board->bustype == GFXBOARD_BUSTYPE_DRACO) {
gb->gfxboard_bank_memory.bget = gfxboard_bget_mem;
gb->gfxboard_bank_memory.bput = gfxboard_bput_mem;
gb->gfxboard_bank_memory.wput = gfxboard_wput_mem;
uaecptr start = 0x20000000;
gb->gfxboardmem_start = start + 0xc00000;
init_board(gb);
copyvrambank(&gb->gfxboard_bank_memory, gb->gfxmem_bank, true);
copyvrambank(&gb->gfxboard_bank_vram_pcem, gb->gfxmem_bank, true);
map_banks(&gb->gfxboard_bank_vram_pcem, gb->gfxboardmem_start >> 16, gb->gfxboard_bank_vram_pcem.allocated_size >> 16, 0);
map_banks(&gb->gfxboard_bank_mmio_wbs_pcem, (start + 0xb00000) >> 16, 1, 0);
map_banks(&gb->gfxboard_bank_special_pcem, (start + 0x000000) >> 16, 1, 0);
gb->pcem_vram_offset = 0x800000;
gb->pcem_vram_mask = 0x3fffff;
gb->pcem_io_mask = 0x3fff;
gb->pcem_mmio_offset = 0x00300000;
gb->pcem_mmio_mask = 0xff;
gb->configured_regs = gb->gfxmem_bank->start >> 16;
gb->gfxboard_intena = 1;
gb->configured_mem = 1;
gb->configured_regs = 1;
}
if (gb->rbc->rtgmem_type == GFXBOARD_ID_VGA) {
init_board(gb);
@ -5513,7 +5545,14 @@ static void special_pcem_put(uaecptr addr, uae_u32 v, int size)
write_log(_T("PCEM SPECIAL PUT %08x %08x %d PC=%08x\n"), addr, v, size, M68K_GETPC);
#endif
if (boardnum == GFXBOARD_ID_RETINA_Z2) {
if (boardnum == GFXBOARD_ID_ALTAIS_Z3) {
addr &= 0xffff;
if (addr >= 0x40) {
gfxboard_bput_io_swap_pcem(addr, v);
}
} else if (boardnum == GFXBOARD_ID_RETINA_Z2) {
addr &= 0x1ffff;
if (addr & 0x10000) {
@ -5859,7 +5898,32 @@ static uae_u32 special_pcem_get(uaecptr addr, int size)
write_log(_T("PCEM SPECIAL GET %08x %d PC=%08x\n"), addr, size, M68K_GETPC);
#endif
if (boardnum == GFXBOARD_ID_RETINA_Z2) {
if (boardnum == GFXBOARD_ID_ALTAIS_Z3) {
addr &= 0xffff;
if (addr >= 0x40) {
v = gfxboard_bget_io_swap_pcem(addr);
} else {
switch(addr)
{
case 3:
v = 2 + 4 + 8;
break;
case 7:
v = 19;
break;
case 11:
v = 0x47;
break;
case 15:
v = 0x54;
break;
}
}
} else if (boardnum == GFXBOARD_ID_RETINA_Z2) {
addr &= 0x1ffff;
if (addr & 0x10000) {

View File

@ -1,2 +0,0 @@
void casablanca_map_overlay(void);

View File

@ -116,4 +116,7 @@ void cpuboard_gvpmaprom(int);
#define BOARD_HARMS 16
#define BOARD_HARMS_SUB_3KPRO 0
#define BOARD_DRACO 17
#define BOARD_DRACO_SUB_DRACO 0
#endif /* UAE_CPUBOARD_H */

6
include/draco.h Normal file
View File

@ -0,0 +1,6 @@
void casablanca_map_overlay(void);
void draco_map_overlay(void);
void draco_init(void);
void draco_reset(void);

View File

@ -83,7 +83,12 @@ int pcem_getvramsize(void);
#define GFXBOARD_ID_PIXEL64 20
#define GFXBOARD_ID_RETINA_Z2 21
#define GFXBOARD_ID_RETINA_Z3 22
#define GFXBOARD_ID_VOODOO5_PCI 23
#define GFXBOARD_ID_ALTAIS_Z3 23
#define GFXBOARD_ID_VOODOO5_PCI 24
#define GFXBOARD_BUSTYPE_Z 0
#define GFXBOARD_BUSTYPE_PCI 1
#define GFXBOARD_BUSTYPE_DRACO 2
struct gfxboard_mode
{
@ -115,5 +120,4 @@ struct gfxboard_func
GFXBOARD_CONFIGURED configured;
};
#endif /* UAE_GFXBOARD_H */

View File

@ -19,6 +19,7 @@ extern bool ncr710_a4091_autoconfig_init(struct autoconfig_info *aci);
extern bool ncr710_warpengine_autoconfig_init(struct autoconfig_info *aci);
extern bool ncr710_zeus040_autoconfig_init(struct autoconfig_info *aci);
extern bool ncr710_magnum40_autoconfig_init(struct autoconfig_info *aci);
extern bool ncr710_draco_init(struct autoconfig_info *aci);
void cpuboard_ncr710_io_bput(uaecptr addr, uae_u32 v);
uae_u32 cpuboard_ncr710_io_bget(uaecptr addr);
@ -38,5 +39,6 @@ extern void a4091_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct ro
extern void wildfire_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
extern void zeus040_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
extern void magnum40_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
extern void draco_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
#endif /* UAE_NCR_SCSI_H */

View File

@ -54,6 +54,7 @@ extern int decode_cloanto_rom_do(uae_u8 *mem, int size, int real_size);
#define ROMTYPE_CB_12GAUGE 0x0004001f
#define ROMTYPE_CB_HARMS3KP 0x00040020
#define ROMTYPE_CB_A1230S1 0x00040021
#define ROMTYPE_CB_DRACO 0x00040022
#define ROMTYPE_FREEZER 0x00080000
#define ROMTYPE_AR 0x00080001
@ -207,6 +208,7 @@ extern int decode_cloanto_rom_do(uae_u8 *mem, int size, int real_size);
#define ROMTYPE_CSMK1SCSI 0x0010008d
#define ROMTYPE_GVPA1208 0x0010008e
#define ROMTYPE_DSP3210 0x0010008f
#define ROMTYPE_ALTAIS 0x00100090
#define ROMTYPE_NOT 0x00800000
#define ROMTYPE_QUAD 0x01000000

View File

@ -17,4 +17,11 @@ void x86_mouse(int port, int x, int y, int z, int b);
int is_x86_cpu(struct uae_prefs*);
typedef void (*X86_INTERRUPT_CALLBACK)(int,bool);
uae_u8 x86_infloppy(int portnum);
void x86_outfloppy(int portnum, uae_u8 v);
void x86_initfloppy(X86_INTERRUPT_CALLBACK);
void x86_floppy_run(void);
#endif /* UAE_X86_H */

View File

@ -41,7 +41,7 @@
#include "uae/ppc.h"
#include "devices.h"
#include "inputdevice.h"
#include "casablanca.h"
#include "draco.h"
bool canbang;
uaecptr highest_ram;
@ -2536,7 +2536,11 @@ static void allocate_memory (void)
a3000hmem_bank.reserved_size = currprefs.mbresmem_high.size;
a3000hmem_bank.mask = a3000hmem_bank.reserved_size - 1;
a3000hmem_bank.start = 0x08000000;
if (currprefs.cs_compatible == CP_DRACO) {
a3000hmem_bank.start = 0x40000000;
} else {
a3000hmem_bank.start = 0x08000000;
}
if (a3000hmem_bank.reserved_size) {
if (!mapped_malloc (&a3000hmem_bank)) {
write_log (_T("Out of memory for a3000highmem.\n"));
@ -2688,6 +2692,10 @@ void map_overlay (int chip)
casablanca_map_overlay();
return;
}
if (currprefs.cs_compatible == CP_DRACO) {
draco_map_overlay();
return;
}
size = chipmem_bank.allocated_size >= 0x180000 ? (chipmem_bank.allocated_size >> 16) : 32;
if (bogomem_aliasing)
@ -3550,11 +3558,23 @@ void restore_banks(void)
}
}
static void map_banks_draco(addrbank *bank, int start, int size, int realsize)
{
// draco has Z2 space mapped at 0x03e80000-0x03fffff
if (start >= 0xe8 && start < 0xf0) {
map_banks(bank, 0x0300 + start, size, realsize);
}
}
void map_banks (addrbank *bank, int start, int size, int realsize)
{
if (start == 0xffffffff)
return;
if (currprefs.cs_compatible == CP_DRACO) {
map_banks_draco(bank, start, size, realsize);
}
#ifdef JIT
if ((bank->jit_read_flag | bank->jit_write_flag) & S_N_ADDR) {
jit_n_addr_unsafe = 1;

View File

@ -1074,6 +1074,29 @@ bool ncr710_magnum40_autoconfig_init(struct autoconfig_info *aci)
return true;
}
bool ncr710_draco_init(struct autoconfig_info *aci)
{
device_add_reset(ncr_reset);
if (!aci->doinit) {
return true;
}
struct ncr_state *ncr = getscsi(aci->rc);
if (!ncr)
return false;
ncr->enabled = true;
ncr->io_start = 0;
ncr->io_end = 0xffff;
ncr->io_mask = 0x7f;
ncr_reset_board(ncr);
aci->addrbank = &ncr_bank_generic;
return true;
}
static void allocscsidevice(struct ncr_state *ncr, int ch, struct scsi_data *handle, int uae_unitnum)
{
handle->privdata = ncr;
@ -1223,4 +1246,14 @@ void magnum40_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romcon
ncr_magnum40->z2 = true;
}
extern void draco_set_scsi_irq(int, int);
void draco_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
{
ncr_add_scsi_unit(&ncr_cpuboard, ch, ci, rc, false);
ncr_cpuboard->irq_func = draco_set_scsi_irq;
ncr_cpuboard->irqlevel = true;
ncr_cpuboard->bank = &ncr_bank_generic;
}
#endif

View File

@ -118,6 +118,7 @@
#define FLOPPYBRIDGE
#define WITH_MIDIEMU
#define WITH_DSP
#define WITH_DRACO
#else

View File

@ -1305,7 +1305,7 @@
<ClCompile Include="..\..\archivers\zip\zip.cpp" />
<ClCompile Include="..\..\aros.rom.cpp" />
<ClCompile Include="..\..\calc.cpp" />
<ClCompile Include="..\..\casablanca.cpp" />
<ClCompile Include="..\..\draco.cpp" />
<ClCompile Include="..\..\cd32_fmv_genlock.cpp" />
<ClCompile Include="..\..\cdtvcr.cpp" />
<ClCompile Include="..\..\cfgfile.cpp" />

View File

@ -820,7 +820,7 @@
<ClCompile Include="..\..\debugmem.cpp">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\casablanca.cpp">
<ClCompile Include="..\..\draco.cpp">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\fpp_native_msvc_80bit.cpp">

View File

@ -299,3 +299,13 @@ void serial2_remove()
{
io_removehandler(serial2.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
}
void draco_serial_init(void **s1, void **s2)
{
serial_reset();
serial1.has_fifo = 1;
serial2.has_fifo = 1;
*s1 = &serial1;
*s2 = &serial2;
}

View File

@ -97,7 +97,7 @@ struct romdata *getromdatabypath (const TCHAR *path)
return NULL;
}
#define NEXT_ROM_ID 311
#define NEXT_ROM_ID 312
#if NEXT_ROM_ID >= MAX_ROMMGR_ROMS
#error Increase MAX_ROMMGR_ROMS!
@ -299,6 +299,8 @@ static struct romdata roms[] = {
ALTROMPN(231, 1, 2, 524288, ROMTYPE_ODD , _T("74095 00 717 02 02 U5"), 0x6ccb0431, 0xa2a43444,0xbeda38be,0x1fa5cabe,0x75fc4def,0x063bcd7a)
{ _T("DraCo Boot ROM v1.3"), 1, 3, 1, 3, _T("DRACO\0"), 131072, 234, 2 | 4, 0, ROMTYPE_EXTCDTV, 0, 0, NULL,
0x0e9c5899,0x82151324,0x01207554,0x60c8a068,0x4793ec18,0x3f744d74, NULL, NULL, 4 },
{ _T("DraCo Boot ROM v1.5"), 1, 5, 1, 5, _T("DRACO\0"), 131072, 311, 2 | 4, 0, ROMTYPE_EXTCDTV, 0, 0, NULL,
0x0f2959d5,0xe8fd5d15,0x08797693,0x99f1df97,0x2fe792fd,0x8146cf1d, NULL, NULL, 4 },
{ _T("CD32 KS ROM v3.1"), 3, 1, 40, 60, _T("CD32\0"), 524288, 18, 1, 0, ROMTYPE_KICKCD32, 0, 0, NULL,
0x1e62d4a5, 0x3525BE88,0x87F79B59,0x29E017B4,0x2380A79E,0xDFEE542D, NULL, NULL, 1 },

99
x86.cpp
View File

@ -19,7 +19,7 @@
#define X86_DEBUG_BRIDGE_IRQ 0
#define X86_IO_PORT_DEBUG 0
#define X86_DEBUG_SPECIAL_IO 0
#define FLOPPY_DEBUG 0
#define FLOPPY_DEBUG 1
#define EMS_DEBUG 0
#define DEBUG_DMA 0
@ -199,6 +199,8 @@ struct x86_bridge
bool vlsi_config;
int a2386flipper;
bool a2386_amigapcdrive;
X86_INTERRUPT_CALLBACK irq_callback;
};
static int x86_found;
@ -528,15 +530,21 @@ void x86_ack_keyboard(void)
void x86_clearirq(uint8_t irqnum)
{
struct x86_bridge *xb = bridges[0];
picintc(1 << irqnum);
if (xb->irq_callback) {
xb->irq_callback(irqnum, false);
} else {
picintc(1 << irqnum);
}
}
void x86_doirq(uint8_t irqnum)
{
struct x86_bridge *xb = bridges[0];
picint(1 << irqnum);
if (xb->irq_callback) {
xb->irq_callback(irqnum, true);
} else {
picint(1 << irqnum);
}
}
struct pc_floppy
@ -1049,10 +1057,16 @@ static void floppy_do_cmd(struct x86_bridge *xb)
}
break;
case 16:
floppy_status[0] = 0x90;
floppy_cmd_len = 1;
break;
default:
floppy_status[0] = 0x80;
floppy_cmd_len = 1;
break;
}
end:
@ -1072,6 +1086,8 @@ end:
}
}
static int draco_force_irq;
static void outfloppy(struct x86_bridge *xb, int portnum, uae_u8 v)
{
switch (portnum)
@ -1096,6 +1112,9 @@ static void outfloppy(struct x86_bridge *xb, int portnum, uae_u8 v)
}
#endif
floppy_dpc = v;
if (xb->type < 0 && 1) {
floppy_dpc |= 8;
}
floppy_num = v & 3;
for (int i = 0; i < 2; i++) {
disk_reserved_setinfo(0, floppy_pc[i].cyl, floppy_pc[i].head, floppy_selected() == i);
@ -1104,6 +1123,7 @@ static void outfloppy(struct x86_bridge *xb, int portnum, uae_u8 v)
case 0x3f5: // data reg
floppy_cmd[floppy_idx] = v;
if (floppy_idx == 0) {
floppy_cmd_len = -1;
switch(v & 31)
{
case 3: // specify
@ -1127,16 +1147,31 @@ static void outfloppy(struct x86_bridge *xb, int portnum, uae_u8 v)
case 10: // read id
floppy_cmd_len = 2;
break;
case 12: // perpendiculaor mode
if (xb->type < 0) {
floppy_cmd_len = 2;
}
break;
case 13: // format track
floppy_cmd_len = 6;
break;
case 15: // seek
floppy_cmd_len = 3;
break;
default:
case 16: // get versionm
if (xb->type < 0) {
floppy_cmd_len = 1;
}
break;
case 19: // configure
if (xb->type < 0) {
floppy_cmd_len = 4;
}
break;
}
if (floppy_cmd_len < 0) {
write_log(_T("Floppy unimplemented command %02x\n"), v);
floppy_cmd_len = 1;
break;
}
}
floppy_idx++;
@ -1168,6 +1203,30 @@ static uae_u8 infloppy(struct x86_bridge *xb, int portnum)
uae_u8 v = 0;
switch (portnum)
{
case 0x3f0: // PS/2 status A (draco)
if (xb->type < 0) {
struct floppy_reserved fr = { 0 };
bool valid_floppy = disk_reserved_getinfo(floppy_num, &fr);
v |= floppy_irq ? 0x80 : 0x00;
v |= 0x40;
v |= fr.wrprot ? 0 : 2;
v |= fr.cyl == 0 ? 0 : 16;
}
break;
case 0x3f1: // PS/2 status B (draco)
if (xb->type < 0) {
v |= 0x80 | 0x40;
if (floppy_dpc & 1)
v |= 0x20;
if ((floppy_dpc >> 4) & 1)
v |= 0x01;
if ((floppy_dpc >> 4) & 2)
v |= 0x02;
}
break;
case 0x3f2:
v = floppy_dpc;
break;
case 0x3f4: // main status
v = 0;
if (!floppy_delay_hsync && (floppy_dpc & 4))
@ -4037,3 +4096,29 @@ bool isa_expansion_init(struct autoconfig_info *aci)
aci->zorro = 0;
return true;
}
void x86_outfloppy(int portnum, uae_u8 v)
{
struct x86_bridge *b = bridges[0];
outfloppy(b, portnum, v);
}
uae_u8 x86_infloppy(int portnum)
{
struct x86_bridge *b = bridges[0];
return infloppy(b, portnum);
}
void x86_floppy_run(void)
{
check_floppy_delay();
}
void x86_initfloppy(X86_INTERRUPT_CALLBACK irq_callback)
{
struct x86_bridge *xb = bridges[0];
if (!xb) {
xb = x86_bridge_alloc();
bridges[0] = xb;
}
xb->type = -1;
xb->irq_callback = irq_callback;
floppy_hardreset();
}