//#include "cross.h" //fmod on certain platforms
static struct {
- Bit8u regs[0x40];
+ Bit8u regs[3 * 0x40];
bool nmi;
bool bcd;
Bit8u reg;
double alarm;
} last;
bool update_ended;
+ int ram_mask;
} cmos;
+extern int x86_cmos_bank;
Bit8u *x86_cmos_regs(Bit8u *regs)
{
if (regs) {
- memcpy(cmos.regs, regs, 0x40);
+ memcpy(cmos.regs, regs, 3 * 0x40);
}
return cmos.regs;
}
// status reg A reading with this (and with other delays actually)
}
+extern void write_log(const char*,...);
+
void cmos_selreg(Bitu port,Bitu val,Bitu iolen) {
- cmos.reg=val & 0x3f;
+ cmos.reg=val & cmos.ram_mask;
cmos.nmi=(val & 0x80)>0;
}
void cmos_writereg(Bitu port,Bitu val,Bitu iolen)
{
- switch (cmos.reg)
+ int reg = cmos.reg;
+ if (reg >= 64 && x86_cmos_bank)
+ reg += 64;
+ reg &= cmos.ram_mask;
+
+ switch (reg)
{
case 0x00: /* Seconds */
case 0x02: /* Minutes */
case 0x03: /* Minutes Alarm */
case 0x05: /* Hours Alarm */
LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Trying to set alarm");
- cmos.regs[cmos.reg]=val;
+ cmos.regs[reg]=val;
break;
case 0x0a: /* Status reg A */
- cmos.regs[cmos.reg]=val & 0x7f;
+ cmos.regs[reg]=val & 0x7f;
if ((val & 0x70)!=0x20) LOG(LOG_BIOS,LOG_ERROR)("CMOS Illegal 22 stage divider value");
cmos.timer.div=(val & 0xf);
cmos_checktimer();
break;
case 0x0b: /* Status reg B */
cmos.bcd=!(val & 0x4);
- cmos.regs[cmos.reg]=val & 0x7f;
+ cmos.regs[reg]=val & 0x7f;
cmos.timer.enabled=(val & 0x40)>0;
if (val&0x10) LOG(LOG_BIOS,LOG_ERROR)("CMOS:Updated ended interrupt not supported yet");
cmos_checktimer();
break;
case 0x0d:/* Status reg D */
- cmos.regs[cmos.reg]=val & 0x80; /*Bit 7=1:RTC Pown on*/
+ cmos.regs[reg]=val & 0x80; /*Bit 7=1:RTC Pown on*/
break;
case 0x0f: /* Shutdown status byte */
- cmos.regs[cmos.reg]=val;// & 0x7f;
+ cmos.regs[reg]=val;// & 0x7f;
break;
default:
- cmos.regs[cmos.reg]=val; // & 0x7f;
+ cmos.regs[reg]=val; // & 0x7f;
LOG(LOG_BIOS,LOG_ERROR)("CMOS:WRite to unhandled register %x",cmos.reg);
}
}
#define MAKE_RETURN(_VAL) (cmos.bcd ? ((((_VAL) / 10) << 4) | ((_VAL) % 10)) : (_VAL));
+extern double vblank_hz;
+extern unsigned long int timeframes;
+extern int vpos;
+
Bitu cmos_readreg(Bitu port,Bitu iolen) {
+#if 0
if (cmos.reg>0x3f) {
LOG(LOG_BIOS,LOG_ERROR)("CMOS:Read from illegal register %x",cmos.reg);
return 0xff;
}
+#endif
Bitu drive_a, drive_b;
Bit8u hdparm;
time_t curtime;
struct tm *loctime;
+ int reg = cmos.reg;
+ if (reg >= 64 && x86_cmos_bank)
+ reg += 64;
+ reg &= cmos.ram_mask;
+
/* Get the current time. */
curtime = time (NULL);
/* Convert it to local time representation. */
loctime = localtime (&curtime);
- switch (cmos.reg) {
+ switch (reg) {
case 0x00: /* Seconds */
return MAKE_RETURN(loctime->tm_sec);
case 0x02: /* Minutes */
case 0x01: /* Seconds Alarm */
case 0x03: /* Minutes Alarm */
case 0x05: /* Hours Alarm */
- return cmos.regs[cmos.reg];
+ return cmos.regs[reg];
case 0x0a: /* Status register A */
- if (0 && PIC_TickIndex()<0.002) {
+ if (vblank_hz > 0 && (timeframes % (int)vblank_hz) == 0 && vpos == 0) { // && PIC_TickIndex()<0.002) {
return (cmos.regs[0x0a]&0x7f) | 0x80;
} else {
return (cmos.regs[0x0a]&0x7f);
case 0x2c:
if(imageDiskList[3] != NULL) return (imageDiskList[3]->sectors);
return 0;
-#endif
case 0x39:
return 0;
case 0x3a:
return 0;
+#endif
case 0x0b: /* Status register B */
case 0x18: /* Extended memory in KB High Byte */
case 0x30: /* Extended memory in KB Low Byte */
case 0x31: /* Extended memory in KB High Byte */
-// LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Read from reg %X : %04X",cmos.reg,cmos.regs[cmos.reg]);
- return cmos.regs[cmos.reg];
+// LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Read from reg %X : %04X",cmos.reg,cmos.regs[reg]);
+ return cmos.regs[reg];
default:
LOG(LOG_BIOS,LOG_NORMAL)("CMOS:Read from reg %X",cmos.reg);
- return cmos.regs[cmos.reg];
+ return cmos.regs[reg];
}
}
// IO_ReadHandleObject ReadHandler[2];
// IO_WriteHandleObject WriteHandler[2];
public:
- CMOS(Section* configuration):Module_base(configuration){
+ CMOS(Section* configuration, int ram_mask):Module_base(configuration){
// WriteHandler[0].Install(0x70,cmos_selreg,IO_MB);
// WriteHandler[1].Install(0x71,cmos_writereg,IO_MB);
// ReadHandler[0].Install(0x71,cmos_readreg,IO_MB);
cmos.timer.enabled=false;
cmos.timer.acknowledged=true;
+ cmos.ram_mask = ram_mask;
cmos.reg=0xa;
cmos_writereg(0x71,0x26,1);
cmos.reg=0xb;
cmos_writereg(0x71,0x2,1); //Struct tm *loctime is of 24 hour format,
cmos.reg=0xd;
cmos_writereg(0x71,0x80,1); /* RTC power on */
+#if 0
// Equipment is updated from bios.cpp and bios_disk.cpp
/* Fill in base memory size, it is 640K always */
cmos.regs[0x15]=(Bit8u)0x80;
cmos.regs[0x18]=(Bit8u)(exsize >> 8);
cmos.regs[0x30]=(Bit8u)exsize;
cmos.regs[0x31]=(Bit8u)(exsize >> 8);
+#endif
}
};
delete test;
}
-void CMOS_Init(Section* sec) {
- test = new CMOS(sec);
+void CMOS_Init(Section* sec, int ram_mask) {
+ test = new CMOS(sec, ram_mask);
sec->AddDestroyFunction(&CMOS_Destroy,true);
}
#include "rommgr.h"
#include "zfile.h"
#include "disk.h"
+#include "driveclick.h"
+#include "scsi.h"
+#include "idecontrollers.h"
+#include "gfxboard.h"
#include "dosbox/dosbox.h"
#include "dosbox/mem.h"
void PAGING_Init(Section * sec);
void MEM_Init(Section * sec);
void MEM_ShutDown(Section * sec);
-void CMOS_Init(Section* sec);
+void CMOS_Init(Section* sec, int);
void CMOS_Destroy(Section* sec);
void PIC_Init(Section* sec);
void PIC_Destroy(Section* sec);
void KEYBOARD_AddBuffer(Bit8u data);
void FPU_Init(Section*);
Bit8u *x86_cmos_regs(Bit8u *regs);
+void MEM_SetVGAHandler(void);
HostPt mono_start, mono_end, color_start, color_end;
int x86_memsize;
int x86_biosstart;
int x86_fpu_enabled;
+int x86_cmos_bank;
+int x86_xrom_start[2];
+int x86_xrom_end[2];
+int x86_vga_mode;
struct x86_bridge
{
int dosbox_cpu;
bool x86_reset_requested;
struct zfile *cmosfile;
- uae_u8 cmosregs[0x40];
+ uae_u8 cmosregs[3 * 0x40];
+ int cmossize;
+ int scamp_idx1, scamp_idx2;
+ struct romconfig *rc;
};
-static bool x86_found;
+static int x86_found;
#define X86_BRIDGE_A1060 0
#define X86_BRIDGE_MAX (X86_BRIDGE_A1060 + 1)
#define IO_KEYBOARD_REGISTER_A2000 0x1fff
#define IO_A2386_CONFIG 0x1f9f
+#define ISVGA() (currprefs.rtgmem_type == GFXBOARD_VGA)
+
static struct x86_bridge *bridges[X86_BRIDGE_MAX];
static struct x86_bridge *x86_bridge_alloc(void)
write_log(_T("8042 CPU reset requested\n"));
}
-void reset_dosbox_cpu(void)
+static void reset_dosbox_cpu(void)
{
CPU_ShutDown(dosbox_sec);
CPU_Init(dosbox_sec);
} else {
reset_dosbox_cpu();
}
+ // reset x86 hd controllers
+ x86_ide_hd_put(-1, 0, 0);
+ x86_xt_hd_bput(-1, 0);
}
uint8_t x86_get_jumpers(void)
break;
default:
- write_log(_T("Unknown bridge IO write %08x = %02x\n"), addr, v);
+ if (addr >= 0x400)
+ write_log(_T("Unknown bridge IO write %08x = %02x\n"), addr, v);
break;
}
break;
default:
- write_log(_T("Unknown bridge IO read %08x\n"), addr);
+ if (addr >= 0x400)
+ write_log(_T("Unknown bridge IO read %08x\n"), addr);
break;
}
static void do_floppy_irq2(void)
{
- write_log(_T("floppy%d irq\n"), floppy_num);
+ write_log(_T("floppy%d irq (enable=%d)\n"), floppy_num, (floppy_dpc & 8) != 0);
if (floppy_dpc & 8) {
floppy_irq = true;
x86_doirq(6);
else if (pcf->phys_cyl > 0)
pcf->phys_cyl--;
+#ifdef DRIVESOUND
+ if (valid_floppy)
+ driveclick_click(fr.num, pcf->phys_cyl);
+#endif
write_log(_T("Floppy%d seeking.. %d\n"), floppy_num, pcf->phys_cyl);
if (pcf->phys_cyl - pcf->seek_offset <= 0) {
floppy_cmd[6], floppy_cmd[7], floppy_cmd[8], floppy_cmd[9]);
write_log(_T("DMA addr %08x len %04x\n"), dmachan[2].page | dmachan[2].addr, dmachan[2].reload);
floppy_delay_hsync = 50;
+ int eot = floppy_cmd[7];
+ bool mt = (floppy_cmd[0] & 0x80) != 0;
+ int cyl = pcf->cyl;
if (valid_floppy) {
if (fr.img && pcf->cyl != floppy_cmd[2]) {
floppy_status[0] |= 0x40; // abnormal termination
pcf->sector++;
if (!(floppy_cmd[0] & 0x80))
break;
+ if (pcf->sector == eot) {
+ pcf->sector = 0;
+ if (pcf->head)
+ pcf->cyl++;
+ if (mt)
+ pcf->head ^= 1;
+ break;
+ }
if (pcf->sector >= fr.secs) {
pcf->sector = 0;
- // todo: check limits
- if (!pcf->head) {
- pcf->head = 1;
- } else {
- break;
- }
+ pcf->head ^= 1;
}
}
- floppy_result[3] = pcf->cyl;
+ floppy_result[3] = cyl;
floppy_result[4] = pcf->head;
floppy_result[5] = pcf->sector + 1;
floppy_result[6] = floppy_cmd[5];
floppy_cmd[6], floppy_cmd[7], floppy_cmd[8], floppy_cmd[9]);
write_log(_T("DMA addr %08x len %04x\n"), dmachan[2].page | dmachan[2].addr, dmachan[2].reload);
floppy_delay_hsync = 50;
+ int eot = floppy_cmd[7];
+ bool mt = (floppy_cmd[0] & 0x80) != 0;
+ int cyl = pcf->cyl;
bool nodata = false;
if (valid_floppy) {
if (fr.img && pcf->cyl != floppy_cmd[2]) {
pcf->sector++;
if (!(floppy_cmd[0] & 0x80))
break;
+ if (pcf->sector == eot) {
+ pcf->sector = 0;
+ if (pcf->head)
+ pcf->cyl++;
+ if (mt)
+ pcf->head ^= 1;
+ break;
+ }
if (pcf->sector >= fr.secs) {
pcf->sector = 0;
- // todo: check limits
- if (!pcf->head) {
- pcf->head = 1;
- }
+ pcf->head ^= 1;
}
}
- floppy_result[3] = pcf->cyl;
+ floppy_result[3] = cyl;
floppy_result[4] = pcf->head;
floppy_result[5] = pcf->sector + 1;
floppy_result[6] = floppy_cmd[5];
}
#if FLOPPY_IO_DEBUG
write_log(_T("DPC: Motormask %02x sel=%d dmaen=%d reset=%d\n"), (v >> 4) & 15, v & 3, (v & 8) ? 1 : 0, (v & 4) ? 0 : 1);
+#endif
+#ifdef DRIVESOUND
+ for (int i = 0; i < 2; i++) {
+ int mask = 0x10 << i;
+ if ((floppy_dpc & mask) != (v & mask)) {
+ struct floppy_reserved fr = { 0 };
+ bool valid_floppy = disk_reserved_getinfo(i, &fr);
+ if (valid_floppy)
+ driveclick_motor(fr.num, (v & mask) ? 1 : 0);
+ }
+ }
#endif
floppy_dpc = v;
floppy_num = v & 3;
void bridge_mono_hit(void)
{
struct x86_bridge *xb = bridges[0];
- set_interrupt(xb, 0);
+ if (xb->amiga_io[IO_MODE_REGISTER] & 8)
+ set_interrupt(xb, 0);
}
void bridge_color_hit(void)
{
struct x86_bridge *xb = bridges[0];
- set_interrupt(xb, 1);
+ if (xb->amiga_io[IO_MODE_REGISTER] & 16)
+ set_interrupt(xb, 1);
}
{
if (addr >= 0xb0000 && addr < 0xb2000) {
// mono
- set_interrupt(xb, 0);
+ if (xb->amiga_io[IO_MODE_REGISTER] & 8)
+ set_interrupt(xb, 0);
}
if (addr >= 0xb8000 && addr < 0xc0000) {
// color
- set_interrupt(xb, 1);
+ if (xb->amiga_io[IO_MODE_REGISTER] & 16)
+ set_interrupt(xb, 1);
}
}
{
if (write && portnum >= 0x3b0 && portnum < 0x3bf) {
// mono crt
- set_interrupt(xb, 2);
+ if (xb->amiga_io[IO_MODE_REGISTER] & 8)
+ set_interrupt(xb, 2);
} else if (write && portnum >= 0x3d0 && portnum < 0x3df) {
// color crt
- set_interrupt(xb, 3);
+ if (xb->amiga_io[IO_MODE_REGISTER] & 16)
+ set_interrupt(xb, 3);
} else if (portnum >= 0x37a && portnum < 0x37b) {
// LPT1
set_interrupt(xb, 5);
}
// Keyboard
// ???
- // Mono video
- if (portnum >= 0x3b0 && portnum < 0x3bf) {
- if (!(enables & 8))
- return false;
- }
- // Color video
- if (portnum >= 0x3d0 && portnum < 0x3df) {
- if (!(enables & 16))
- return false;
- }
return true;
}
struct x86_bridge *xb = bridges[0];
uae_u8 *io = xb->io_ports;
int aio = -1;
+ uae_u8 enables = xb->amiga_io[IO_MODE_REGISTER];
+ bool mda_emu = (enables & 8) != 0;
+ bool cga_emu = (enables & 16) != 0;
if (portnum >= 0x400)
return;
aio = 0x1f;
break;
+ // vga
+ case 0x3c2:
+ x86_vga_mode = v & 1;
+ case 0x3c0:
+ case 0x3c1:
+ case 0x3c3:
+ case 0x3c4:
+ case 0x3c5:
+ case 0x3c6:
+ case 0x3c7:
+ case 0x3c8:
+ case 0x3c9:
+ case 0x3ca:
+ case 0x3cb:
+ case 0x3cc:
+ case 0x3cd:
+ case 0x3ce:
+ case 0x3cf:
+ case 0x3b9:
+ if (ISVGA()) {
+ vga_io_put(portnum, v);
+ }
+ break;
+
// mono video
case 0x3b0:
case 0x3b2:
case 0x3b4:
case 0x3b6:
- aio = 0x1ff;
+ if (mda_emu) {
+ aio = 0x1ff;
+ } else if (ISVGA()) {
+ if (x86_vga_mode == 0)
+ vga_io_put(portnum, v);
+ }
break;
case 0x3b1:
case 0x3b3:
case 0x3b5:
case 0x3b7:
- aio = 0x2a1 + (xb->amiga_io[0x1ff] & 15) * 2;
+ if (mda_emu) {
+ aio = 0x2a1 + (xb->amiga_io[0x1ff] & 15) * 2;
+ } else if (ISVGA()) {
+ if (x86_vga_mode == 0)
+ vga_io_put(portnum, v);
+ }
break;
case 0x3b8:
- aio = 0x2ff;
+ if (mda_emu) {
+ aio = 0x2ff;
+ }
break;
// color video
case 0x3d2:
case 0x3d4:
case 0x3d6:
- aio = 0x21f;
+ if (cga_emu) {
+ aio = 0x21f;
+ } else if (ISVGA()) {
+ if (x86_vga_mode == 1)
+ vga_io_put(portnum, v);
+ }
break;
case 0x3d1:
case 0x3d3:
case 0x3d5:
case 0x3d7:
- aio = 0x2c1 + (xb->amiga_io[0x21f] & 15) * 2;
+ if (cga_emu) {
+ aio = 0x2c1 + (xb->amiga_io[0x21f] & 15) * 2;
+ } else if (ISVGA()) {
+ if (x86_vga_mode == 1)
+ vga_io_put(portnum, v);
+ }
break;
case 0x3d8:
- aio = 0x23f;
+ if (cga_emu) {
+ aio = 0x23f;
+ }
break;
case 0x3d9:
- aio = 0x25f;
+ if (cga_emu) {
+ aio = 0x25f;
+ }
break;
case 0x3dd:
- aio = 0x29f;
+ if (cga_emu) {
+ aio = 0x29f;
+ }
+ break;
+
+ case 0x3ba:
+ if (cga_emu) {
+ aio = 0x1f;
+ } else if (ISVGA()) {
+ if (x86_vga_mode == 0)
+ vga_io_put(portnum, v);
+ }
+ break;
+ case 0x3da:
+ if (cga_emu) {
+ aio = 0x1f;
+ } else if (ISVGA()) {
+ if (x86_vga_mode == 1)
+ vga_io_put(portnum, v);
+ }
break;
case 0x378:
aio = 0x1df;
break;
- case 0x3ba:
case 0x3bb:
case 0x3bc:
case 0x3bd:
case 0x3be:
case 0x3bf:
- case 0x3da:
+ if (mda_emu) {
+ aio = 0x1f;
+ }
+ break;
+
case 0x3de:
case 0x3df:
- aio = 0x1f;
+ if (cga_emu) {
+ aio = 0x1f;
+ }
+ break;
+
+ // A2386SX only
+ case 0xe8:
+ xb->scamp_idx1 = v;
+ break;
+ case 0xec:
+ xb->scamp_idx2 = v;
+ break;
+ case 0xed:
+ write_log(_T("VL82C107 %02x = %02x\n"), xb->scamp_idx2, v);
+ if (xb->scamp_idx2 == 0x1d) {
+ x86_cmos_bank = (v & 0x20) ? 1 : 0;
+ }
break;
// floppy
outfloppy(xb, portnum, v);
break;
+ // at ide 1
+ case 0x170:
+ case 0x171:
+ case 0x172:
+ case 0x173:
+ case 0x174:
+ case 0x175:
+ case 0x176:
+ case 0x177:
+ x86_ide_hd_put(portnum, v, 0);
+ break;
+ // at ide 0
+ case 0x1f0:
+ case 0x1f1:
+ case 0x1f2:
+ case 0x1f3:
+ case 0x1f4:
+ case 0x1f5:
+ case 0x1f6:
+ case 0x1f7:
+ x86_ide_hd_put(portnum, v, 0);
+ break;
+
+ // xt hd
+ case 0x320:
+ case 0x321:
+ case 0x322:
+ case 0x323:
+ x86_xt_hd_bput(portnum, v);
+ break;
+
+ // universal xt bios
+ case 0x300:
+ case 0x301:
+ case 0x302:
+ case 0x303:
+ case 0x304:
+ case 0x305:
+ case 0x306:
+ case 0x307:
+ case 0x308:
+ case 0x309:
+ case 0x30a:
+ case 0x30b:
+ case 0x30c:
+ case 0x30d:
+ case 0x30e:
+ case 0x30f:
+ x86_ide_hd_put(portnum, v, 0);
+ break;
+
default:
write_log(_T("X86_OUT unknown %02x %02x\n"), portnum, v);
break;
}
void portout16(uint16_t portnum, uint16_t value)
{
- write_log(_T("portout16 %08x %04x\n"), portnum, value);
+ switch (portnum)
+ {
+ case 0x170:
+ case 0x1f0:
+ case 0x300:
+ x86_ide_hd_put(portnum, value, 1);
+ break;
+ default:
+ portout(portnum, value);
+ portout(portnum + 1, value >> 8);
+ break;
+ }
}
+static void portout32(uint16_t portnum, uint32_t value)
+{
+ switch (portnum)
+ {
+ case 0x170:
+ case 0x1f0:
+ case 0x300:
+ x86_ide_hd_put(portnum, value >> 16, 1);
+ x86_ide_hd_put(portnum, value, 1);
+ break;
+ default:
+ write_log(_T("portout32 %08x %08x\n"), portnum, value);
+ break;
+ }
+}
+
uint8_t portin(uint16_t portnum)
{
struct x86_bridge *xb = bridges[0];
int aio = -1;
+ uae_u8 enables = xb->amiga_io[IO_MODE_REGISTER];
+ bool mda_emu = (enables & 8) != 0;
+ bool cga_emu = (enables & 16) != 0;
if (!is_port_enabled(xb, portnum))
return 0;
aio = 0x19f; // ?
break;
+ // vga
+ case 0x3c0:
+ case 0x3c1:
+ case 0x3c2:
+ case 0x3c3:
+ case 0x3c4:
+ case 0x3c5:
+ case 0x3c6:
+ case 0x3c7:
+ case 0x3c8:
+ case 0x3c9:
+ case 0x3ca:
+ case 0x3cb:
+ case 0x3cc:
+ case 0x3cd:
+ case 0x3ce:
+ case 0x3cf:
+ case 0x3b9:
+ if (ISVGA()) {
+ v = vga_io_get(portnum);
+ }
+ break;
+
// mono video
case 0x3b0:
xb->pc_irq3a = false;
case 0x3b2:
case 0x3b4:
case 0x3b6:
- aio = 0x1ff;
+ if (mda_emu) {
+ aio = 0x1ff;
+ } else if (ISVGA()) {
+ if (x86_vga_mode == 0)
+ v = vga_io_get(portnum);
+ }
break;
case 0x3b1:
case 0x3b3:
case 0x3b5:
case 0x3b7:
- aio = 0x2a1 + (xb->amiga_io[0x1ff] & 15) * 2;
+ if (mda_emu) {
+ aio = 0x2a1 + (xb->amiga_io[0x1ff] & 15) * 2;
+ } else if (ISVGA()) {
+ if (x86_vga_mode == 0)
+ v = vga_io_get(portnum);
+ }
break;
case 0x3b8:
- aio = 0x2ff;
+ if (mda_emu) {
+ aio = 0x2ff;
+ }
break;
// color video
case 0x3d2:
case 0x3d4:
case 0x3d6:
- aio = 0x21f;
+ if (cga_emu) {
+ aio = 0x21f;
+ } else if (ISVGA()) {
+ if (x86_vga_mode == 1)
+ v = vga_io_get(portnum);
+ }
break;
case 0x3d1:
case 0x3d3:
case 0x3d5:
case 0x3d7:
- aio = 0x2c1 + (xb->amiga_io[0x21f] & 15) * 2;
+ if (cga_emu) {
+ aio = 0x2c1 + (xb->amiga_io[0x21f] & 15) * 2;
+ } else if (ISVGA()) {
+ if (x86_vga_mode == 1)
+ v = vga_io_get(portnum);
+ }
break;
case 0x3d8:
- aio = 0x23f;
+ if (cga_emu) {
+ aio = 0x23f;
+ }
break;
case 0x3d9:
- aio = 0x25f;
+ if (cga_emu) {
+ aio = 0x25f;
+ }
break;
+
case 0x3ba:
+ if (mda_emu) {
+ v = 0;
+ // not really correct but easy.
+ if (vpos < 20)
+ v |= 8 | 1;
+ if (get_cycles() - last_cycles > maxhpos / 2)
+ v |= 1;
+ last_cycles = get_cycles();
+ } else if (ISVGA()) {
+ if (x86_vga_mode == 0)
+ v = vga_io_get(portnum);
+ }
+ break;
case 0x3da:
- v = 0;
- // not really correct but easy.
- if (vpos < 20)
- v |= 8 | 1;
- if (get_cycles() - last_cycles > maxhpos / 2)
- v |= 1;
- last_cycles = get_cycles();
+ if (cga_emu) {
+ v = 0;
+ // not really correct but easy.
+ if (vpos < 20)
+ v |= 8 | 1;
+ if (get_cycles() - last_cycles > maxhpos / 2)
+ v |= 1;
+ last_cycles = get_cycles();
+ } else if (ISVGA()) {
+ if (x86_vga_mode == 1)
+ v = vga_io_get(portnum);
+ }
break;
case 0x3dd:
- aio = 0x29f;
+ if (cga_emu) {
+ aio = 0x29f;
+ }
break;
case 0x3bb:
case 0x3bd:
case 0x3be:
case 0x3bf:
+ if (mda_emu) {
+ aio = 0x1f;
+ }
+ break;
case 0x3de:
case 0x3df:
- aio = 0x1f;
+ if (cga_emu) {
+ aio = 0x1f;
+ }
break;
// floppy
v = x86_in_keyboard(0x64);
}
break;
+
+ case 0xed:
+ if (xb->scamp_idx2 == 0x1d) {
+ v = x86_cmos_bank ? 0x20 : 0x00;
+ }
+ break;
+
+ // at ide 1
+ case 0x170:
+ case 0x171:
+ case 0x172:
+ case 0x173:
+ case 0x174:
+ case 0x175:
+ case 0x176:
+ case 0x177:
+ v = x86_ide_hd_get(portnum, 0);
+ break;
+ // at ide 0
+ case 0x1f0:
+ case 0x1f1:
+ case 0x1f2:
+ case 0x1f3:
+ case 0x1f4:
+ case 0x1f5:
+ case 0x1f6:
+ case 0x1f7:
+ v = x86_ide_hd_get(portnum, 0);
+ break;
+
+ // xt hd
+ case 0x320:
+ case 0x321:
+ case 0x322:
+ case 0x323:
+ v = x86_xt_hd_bget(portnum);
+ break;
+
+ // universal xt bios
+ case 0x300:
+ case 0x301:
+ case 0x302:
+ case 0x303:
+ case 0x304:
+ case 0x305:
+ case 0x306:
+ case 0x307:
+ case 0x308:
+ case 0x309:
+ case 0x30a:
+ case 0x30b:
+ case 0x30c:
+ case 0x30d:
+ case 0x30e:
+ case 0x30f:
+ v = x86_ide_hd_get(portnum, 0);
+ break;
+
default:
write_log(_T("X86_IN unknown %02x\n"), portnum);
return 0;
}
uint16_t portin16(uint16_t portnum)
{
- write_log(_T("portin16 %08x\n"), portnum);
- return 0;
+ uae_u16 v = 0;
+ switch (portnum)
+ {
+ case 0x170:
+ case 0x1f0:
+ case 0x300:
+ v = x86_ide_hd_get(portnum, 1);
+ break;
+ default:
+ write_log(_T("portin16 %08x\n"), portnum);
+ break;
+ }
+ return v;
+}
+static uint32_t portin32(uint16_t portnum)
+{
+ uint32_t v = 0;
+ switch (portnum)
+ {
+ case 0x170:
+ case 0x1f0:
+ case 0x300:
+ v = x86_ide_hd_get(portnum, 1) << 16;
+ v |= x86_ide_hd_get(portnum, 1);
+ break;
+ default:
+ write_log(_T("portin32 %08x\n"), portnum);
+ break;
+ }
+ return v;
}
void write86(uint32_t addr32, uint8_t value)
addr32 &= 0xFFFFF;
if (addr32 >= xb->pc_maxbaseram && addr32 < 0xa0000)
return;
+ if (addr32 >= x86_xrom_start[0] && addr32 < x86_xrom_end[0])
+ return;
+ if (addr32 >= x86_xrom_start[1] && addr32 < x86_xrom_end[1])
+ return;
set_pc_address_access(xb, addr32);
xb->pc_ram[addr32] = value;
}
addr32 &= 0xFFFFF;
if (addr32 >= xb->pc_maxbaseram && addr32 < 0xa0000)
return;
+ if (addr32 >= x86_xrom_start[0] && addr32 < x86_xrom_end[0])
+ return;
+ if (addr32 >= x86_xrom_start[1] && addr32 < x86_xrom_end[1])
+ return;
set_pc_address_access(xb, addr32);
xb->pc_ram[addr32] = value & 0xff;
xb->pc_ram[addr32 + 1] = value >> 8;
void x86_bridge_free(void)
{
x86_bridge_reset();
- x86_found = false;
+ x86_found = 0;
}
void x86_bridge_reset(void)
{
+ x86_xrom_start[0] = x86_xrom_end[0] = 0;
+ x86_xrom_start[1] = x86_xrom_end[1] = 0;
for (int i = 0; i < X86_BRIDGE_MAX; i++) {
struct x86_bridge *xb = bridges[i];
if (!xb)
if (xb->cmosfile) {
uae_u8 *regs = x86_cmos_regs(NULL);
zfile_fseek(xb->cmosfile, 0, SEEK_SET);
- zfile_fwrite(regs, 1, 0x40, xb->cmosfile);
+ zfile_fwrite(regs, 1, xb->cmossize, xb->cmosfile);
}
CPU_ShutDown(dosbox_sec);
CMOS_Destroy(dosbox_sec);
static void bridge_reset(struct x86_bridge *xb)
{
+ uae_u8 *temp[2];
xb->x86_reset = true;
xb->configured = 0;
xb->amiga_forced_interrupts = false;
xb->pc_irq3a = xb->pc_irq3b = xb->pc_irq7 = false;
memset(xb->amiga_io, 0, 0x10000);
memset(xb->io_ports, 0, 0x10000);
+ for (int i = 0; i < 2; i++) {
+ temp[i] = NULL;
+ if (x86_xrom_start[i]) {
+ temp[i] = xmalloc(uae_u8, x86_xrom_end[i] - x86_xrom_start[i]);
+ memcpy(temp[i], xb->pc_ram + x86_xrom_start[i], x86_xrom_end[i] - x86_xrom_start[i]);
+ }
+ }
memset(xb->pc_ram, 0, 0x100000 - xb->bios_size);
+ for (int i = 0; i < 2; i++) {
+ if (temp[i]) {
+ memcpy(xb->pc_ram + x86_xrom_start[i], temp[i], x86_xrom_end[i] - x86_xrom_start[i]);
+ xfree(temp[i]);
+ }
+ }
xb->amiga_io[IO_CONTROL_REGISTER] = 0xfe;
xb->amiga_io[IO_PC_INTERRUPT_CONTROL] = 0xff;
xb->amiga_io[IO_INTERRUPT_MASK] = 0xff;
xb->amiga_io[IO_MODE_REGISTER] = 0x00;
xb->amiga_io[IO_PC_INTERRUPT_STATUS] = 0xfe;
+ x86_cmos_bank = 0;
if (xb->type >= TYPE_2286) {
int sel1 = (xb->settings >> 10) & 1;
sel1 = 0;
sel2 = 1;
}
- xb->amiga_io[IO_MODE_REGISTER] = sel1 << 5;
- xb->amiga_io[IO_MODE_REGISTER] = sel2 << 6;
+ xb->amiga_io[IO_MODE_REGISTER] |= sel1 << 5;
+ xb->amiga_io[IO_MODE_REGISTER] |= sel2 << 6;
}
inittiming();
{
struct x86_bridge *xb = bridges[0];
if (!xb) {
- if (x86_found)
+ if (x86_found > 0)
return X86_STATE_STOP;
+ else if (x86_found < 0)
+ return X86_STATE_INACTIVE;
if (is_device_rom(&currprefs, ROMTYPE_A1060, 0) < 0 &&
is_device_rom(&currprefs, ROMTYPE_A2088, 0) < 0 &&
is_device_rom(&currprefs, ROMTYPE_A2088T, 0) < 0 &&
is_device_rom(&currprefs, ROMTYPE_A2286, 0) < 0 &&
is_device_rom(&currprefs, ROMTYPE_A2386, 0) < 0) {
- x86_found = true;
+ x86_found = -1;
return X86_STATE_INACTIVE;
+ } else {
+ x86_found = 1;
}
}
if (!xb || xb->x86_reset)
return X86_STATE_ACTIVE;
}
+static void load_vga_bios(void)
+{
+ struct x86_bridge *xb = bridges[0];
+ if (!xb || !ISVGA())
+ return;
+ struct zfile *zf = read_device_rom(&currprefs, ROMTYPE_x86_VGA, 0, NULL);
+ x86_xrom_start[1] = 0xc0000;
+ x86_xrom_end[1] = x86_xrom_start[1];
+ if (zf) {
+ x86_xrom_end[1] += zfile_fread(MemBase + 0xc0000, 1, 65536, zf);
+ zfile_fclose(zf);
+ x86_xrom_end[1] += 4095;
+ x86_xrom_end[1] &= ~4095;
+ }
+ if (xb->dosbox_cpu) {
+ MEM_ShutDown(dosbox_sec);
+ MEM_Init(dosbox_sec);
+ MEM_SetVGAHandler();
+ }
+}
+
+void x86_xt_ide_bios(struct zfile *z)
+{
+ struct x86_bridge *xb = bridges[0];
+ if (!xb || !z)
+ return;
+ x86_xrom_start[0] = 0xec000;
+ x86_xrom_end[0] = x86_xrom_start[0] + 0x4000;
+ zfile_fread(xb->pc_ram + x86_xrom_start[0], 1, 32768, z);
+ if (xb->dosbox_cpu) {
+ MEM_ShutDown(dosbox_sec);
+ MEM_Init(dosbox_sec);
+ if (ISVGA()) {
+ MEM_SetVGAHandler();
+ }
+ }
+}
+
static const uae_u8 a1060_autoconfig[16] = { 0xc4, 0x01, 0x80, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static const uae_u8 a2386_autoconfig[16] = { 0xc4, 0x67, 0x80, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
if (!xb)
return &expamem_null;
bridges[0] = xb;
+ xb->rc = rc;
xb->type = type;
xb->io_ports = xcalloc(uae_u8, 0x10000);
xb->amiga_io = xcalloc(uae_u8, 0x10000);
+ x86_xrom_start[0] = x86_xrom_end[0] = 0;
+ x86_xrom_start[1] = x86_xrom_end[1] = 0;
xb->settings = rc->device_settings;
if (xb->type >= TYPE_2286) {
xb->dosbox_cpu = ((xb->settings >> 19) & 3) + 1;
color_start = xb->pc_ram + 0xb8000;
color_end = xb->pc_ram + 0xc0000;
x86_biosstart = 0x100000 - xb->bios_size;
+ MemBase = xb->pc_ram;
if (xb->dosbox_cpu) {
x86_fpu_enabled = (xb->settings >> 22) & 1;
- MemBase = xb->pc_ram;
dosbox_sec = new Section_prop("dummy");
MEM_Init(dosbox_sec);
PAGING_Init(dosbox_sec);
- CMOS_Init(dosbox_sec);
+ CMOS_Init(dosbox_sec, xb->type == TYPE_2386 ? 0x7f : 0x3f);
PIC_Init(dosbox_sec);
FPU_Init(dosbox_sec);
if (xb->type >= TYPE_2286) {
+ xb->cmossize = xb->type == TYPE_2386 ? 192 : 64;
xb->cmosfile = zfile_fopen(currprefs.flashfile, _T("rb+"), ZFD_NORMAL);
if (!xb->cmosfile) {
xb->cmosfile = zfile_fopen(currprefs.flashfile, _T("wb"));
}
memset(xb->cmosregs, 0, sizeof xb->cmosregs);
if (xb->cmosfile) {
- if (zfile_fread(xb->cmosregs, 1, 0x40, xb->cmosfile) >= 0x40) {
+ if (zfile_fread(xb->cmosregs, 1, xb->cmossize, xb->cmosfile) == xb->cmossize) {
x86_cmos_regs(xb->cmosregs);
}
}
}
}
+ if (ISVGA()) {
+ MEM_SetVGAHandler();
+ load_vga_bios();
+ }
xb->pc_jumpers = (xb->settings & 0xff) ^ ((0x80 | 0x40) | (0x20 | 0x10));
Bit32s ticksDone;
Bit32u ticksScheduled;
-#if 0
-Bit8u mem_readb(PhysPt address)
-{
- return mem_readb_inline(address);
-}
-Bit16u mem_readw(PhysPt address)
-{
- return mem_readw_inline(address);
-}
-Bit32u mem_readd(PhysPt address)
-{
- return mem_readd_inline(address);
-}
-void mem_writeb(PhysPt address, Bit8u val)
-{
- mem_writeb_inline(address, val);
-}
-void mem_writew(PhysPt address, Bit16u val)
-{
- mem_writew_inline(address, val);
-}
-void mem_writed(PhysPt address, Bit32u val)
-{
- mem_writed_inline(address, val);
-}
-Bit16u mem_unalignedreadw(PhysPt address)
-{
- return mem_readb_inline(address) |
- mem_readb_inline(address + 1) << 8;
-}
-Bit32u mem_unalignedreadd(PhysPt address)
-{
- return mem_readb_inline(address) |
- (mem_readb_inline(address + 1) << 8) |
- (mem_readb_inline(address + 2) << 16) |
- (mem_readb_inline(address + 3) << 24);
-}
-void mem_unalignedwritew(PhysPt address, Bit16u val)
-{
- mem_writeb_inline(address, (Bit8u)val);
- val >>= 8;
- mem_writeb_inline(address + 1, (Bit8u)val);
-}
-void mem_unalignedwrited(PhysPt address, Bit32u val)
-{
- mem_writeb_inline(address, (Bit8u)val);
- val >>= 8;
- mem_writeb_inline(address + 1, (Bit8u)val);
- val >>= 8;
- mem_writeb_inline(address + 2, (Bit8u)val);
- val >>= 8;
- mem_writeb_inline(address + 3, (Bit8u)val);
-}
-#endif
-
void IO_WriteB(Bitu port, Bitu val)
{
portout(port, val);
}
void IO_WriteW(Bitu port, Bitu val)
{
- write_log(_T("IO_WriteW %04x %04x\n"), port, val);
+ portout16(port, val);
}
void IO_WriteD(Bitu port, Bitu val)
{
- write_log(_T("IO_WriteW %04x %08x\n"), port, val);
+ portout32(port, val);
}
Bitu IO_ReadB(Bitu port)
{
}
Bitu IO_ReadW(Bitu port)
{
- write_log(_T("IO_ReadW %04x \n"), port);
- return 0;
+ return portin16(port);
}
Bitu IO_ReadD(Bitu port)
{
- write_log(_T("IO_ReadW %04x \n"), port);
- return 0;
+ return portin32(port);
}
void TIMER_SetGate2(bool v)
void E_Exit(char *format, ...)
{
+ va_list parms;
+ va_start(parms, format);
+ char buffer[1000];
+ vsnprintf(buffer, sizeof(buffer), format, parms);
+ write_log("DOSBOX E_Exit: %s\n", buffer);
+ va_end(parms);
}
void GFX_ShowMsg(const char *format, ...)
{
+ va_list parms;
+ va_start(parms, format);
+ char buffer[1000];
+ vsnprintf(buffer, sizeof(buffer), format, parms);
+ write_log("DOSBOX GFX_ShowMsg: %s\n", buffer);
+ va_end(parms);
}