private:
static bool inited;
public:
- CPU(Section* configuration):Module_base(configuration) {
+ CPU(Section* configuration, int cpumode, int cpuarch):Module_base(configuration) {
// if(inited) {
// Change_Config(configuration);
// return;
#endif
MAPPER_AddHandler(CPU_CycleDecrease,MK_f11,MMOD1,"cycledown","Dec Cycles");
MAPPER_AddHandler(CPU_CycleIncrease,MK_f12,MMOD1,"cycleup" ,"Inc Cycles");
- Change_Config(configuration);
+ Change_Config(configuration, cpumode, cpuarch);
CPU_JMP(false,0,0,0); //Setup the first cpu core
}
- bool Change_Config(Section* newconfig){
+ bool Change_Config(Section* newconfig, int cpumode, int cpuarch){
Section_prop * section=static_cast<Section_prop *>(newconfig);
CPU_AutoDetermineMode=CPU_AUTODETERMINE_NONE;
//CPU_CycleLeft=0;//needed ?
CPU_CycleUp=section->Get_int("cycleup");
CPU_CycleDown=section->Get_int("cycledown");
//std::string core(section->Get_string("core"));
+
std::string core = "simple";
+ if (cpumode == 2)
+ core = "normal";
+ else if (cpumode == 3)
+ core = "full";
+ else if (cpumode == 4)
+ core = "auto";
+
cpudecoder=&CPU_Core_Normal_Run;
if (core == "normal") {
cpudecoder=&CPU_Core_Normal_Run;
CPU_ArchitectureType = CPU_ARCHTYPE_MIXED;
//std::string cputype(section->Get_string("cputype"));
+
std::string cputype = "auto";
+ if (cpuarch == 1)
+ cputype = "386";
+ else if (cpuarch == 2)
+ cputype = "386_prefetch";
+ else if (cpuarch == 3)
+ cputype = "386_slow";
+ else if (cpuarch == 4)
+ cputype = "486_slow";
+ else if (cpuarch == 5)
+ cputype = "486_prefetch";
+ else if (cpuarch == 6)
+ cputype = "pentium_slow";
+
if (cputype == "auto") {
CPU_ArchitectureType = CPU_ARCHTYPE_MIXED;
} else if (cputype == "386") {
test = NULL;
}
-void CPU_Init(Section* sec) {
- test = new CPU(sec);
+void CPU_Init(Section* sec, int cpumode, int cpuarch) {
+ test = new CPU(sec, cpumode, cpuarch);
sec->AddDestroyFunction(&CPU_ShutDown,true);
}
//initialize static members
}
}
-void MEM_ResetPageHandler(Bitu phys_page, Bitu pages) {
+void MEM_ResetPageHandlerRAM(Bitu phys_page, Bitu pages) {
for (;pages>0;pages--) {
memory.phandlers[phys_page]=&ram_page_handler;
phys_page++;
}
}
+void MEM_ResetPageHandlerROM(Bitu phys_page, Bitu pages)
+{
+ for (; pages>0; pages--) {
+ memory.phandlers[phys_page] = &rom_page_handler;
+ phys_page++;
+ }
+}
+
Bitu mem_strlen(PhysPt pt) {
Bitu x=0;
while (x<1024) {
typedef Bit32s Bits;
typedef double Real64;
+#define C_UNALIGNED_MEMORY
+
#define LONGTYPE(a) a##LL
#define INLINE __inline
Working on big or little endian machines
*/
-#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
-
void bridge_mono_hit(void);
void bridge_color_hit(void);
extern HostPt mono_start, mono_end, color_start, color_end;
bridge_color_hit();
}
+#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
+
static INLINE Bit8u host_readb(HostPt off) {
return off[0];
}
return *(Bit32u *)off;
}
static INLINE void host_writeb(HostPt off,Bit8u val) {
+ bridge_special_addr_check(off);
*(Bit8u *)(off)=val;
}
static INLINE void host_writew(HostPt off,Bit16u val) {
+ bridge_special_addr_check(off);
*(Bit16u *)(off)=val;
}
static INLINE void host_writed(HostPt off,Bit32u val) {
+ bridge_special_addr_check(off);
*(Bit32u *)(off)=val;
}
void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler, PageHandler *mmiohandler);
void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler);
-void MEM_ResetPageHandler(Bitu phys_page, Bitu pages);
+void MEM_ResetPageHandlerRAM(Bitu phys_page, Bitu pages);
+void MEM_ResetPageHandlerROM(Bitu phys_page, Bitu pages);
#ifdef _MSC_VER
#include "cpu.h"
#include "callback.h"
#include "pic.h"
-//#include "timer.h"
+#include "timer.h"
#include "setup.h"
#define PIC_QUEUESIZE 512
return true;
}
-#if 0
/* The TIMER Part */
struct TickerBlock {
TIMER_TickHandler handler;
ticker=nextticker;
}
}
-#endif
void x86_pic_write(Bitu port, Bitu val)
{
}
class PIC:public Module_base{
-private:
+//private:
// IO_ReadHandleObject ReadHandler[4];
// IO_WriteHandleObject WriteHandler[4];
public:
--- /dev/null
+/*
+ * Copyright (C) 2002-2010 The DOSBox Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: timer.cpp,v 1.49 2009-04-10 09:53:04 c2woody Exp $ */
+
+#include <math.h>
+#include "dosbox.h"
+#include "inout.h"
+#include "pic.h"
+#include "mem.h"
+//#include "mixer.h"
+#include "timer.h"
+#include "setup.h"
+
+static INLINE void BIN2BCD(Bit16u& val) {
+ Bit16u temp=val%10 + (((val/10)%10)<<4)+ (((val/100)%10)<<8) + (((val/1000)%10)<<12);
+ val=temp;
+}
+
+static INLINE void BCD2BIN(Bit16u& val) {
+ Bit16u temp= (val&0x0f) +((val>>4)&0x0f) *10 +((val>>8)&0x0f) *100 +((val>>12)&0x0f) *1000;
+ val=temp;
+}
+
+struct PIT_Block {
+ Bitu cntr;
+ float delay;
+ double start;
+
+ Bit16u read_latch;
+ Bit16u write_latch;
+
+ Bit8u mode;
+ Bit8u latch_mode;
+ Bit8u read_state;
+ Bit8u write_state;
+
+ bool bcd;
+ bool go_read_latch;
+ bool new_mode;
+ bool counterstatus_set;
+ bool counting;
+ bool update_count;
+};
+
+static PIT_Block pit[3];
+static bool gate2;
+
+static Bit8u latched_timerstatus;
+// the timer status can not be overwritten until it is read or the timer was
+// reprogrammed.
+static bool latched_timerstatus_locked;
+
+static void PIT0_Event(Bitu /*val*/) {
+ PIC_ActivateIRQ(0);
+ if (pit[0].mode != 0) {
+ pit[0].start += pit[0].delay;
+
+ if (GCC_UNLIKELY(pit[0].update_count)) {
+ pit[0].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[0].cntr));
+ pit[0].update_count=false;
+ }
+ PIC_AddEvent(PIT0_Event,pit[0].delay);
+ }
+}
+
+static bool counter_output(Bitu counter) {
+ PIT_Block * p=&pit[counter];
+ double index=PIC_FullIndex()-p->start;
+ switch (p->mode) {
+ case 0:
+ if (p->new_mode) return false;
+ if (index>p->delay) return true;
+ else return false;
+ break;
+ case 2:
+ if (p->new_mode) return true;
+ index=fmod(index,(double)p->delay);
+ return index>0;
+ case 3:
+ if (p->new_mode) return true;
+ index=fmod(index,(double)p->delay);
+ return index*2<p->delay;
+ case 4:
+ //Only low on terminal count
+ // if(fmod(index,(double)p->delay) == 0) return false; //Maybe take one rate tick in consideration
+ //Easiest solution is to report always high (Space marines uses this mode)
+ return true;
+ default:
+ LOG(LOG_PIT,LOG_ERROR)("Illegal Mode %d for reading output",p->mode);
+ return true;
+ }
+}
+static void status_latch(Bitu counter) {
+ // the timer status can not be overwritten until it is read or the timer was
+ // reprogrammed.
+ if(!latched_timerstatus_locked) {
+ PIT_Block * p=&pit[counter];
+ latched_timerstatus=0;
+ // Timer Status Word
+ // 0: BCD
+ // 1-3: Timer mode
+ // 4-5: read/load mode
+ // 6: "NULL" - this is 0 if "the counter value is in the counter" ;)
+ // should rarely be 1 (i.e. on exotic modes)
+ // 7: OUT - the logic level on the Timer output pin
+ if(p->bcd)latched_timerstatus|=0x1;
+ latched_timerstatus|=((p->mode&7)<<1);
+ if((p->read_state==0)||(p->read_state==3)) latched_timerstatus|=0x30;
+ else if(p->read_state==1) latched_timerstatus|=0x10;
+ else if(p->read_state==2) latched_timerstatus|=0x20;
+ if(counter_output(counter)) latched_timerstatus|=0x80;
+ if(p->new_mode) latched_timerstatus|=0x40;
+ // The first thing that is being read from this counter now is the
+ // counter status.
+ p->counterstatus_set=true;
+ latched_timerstatus_locked=true;
+ }
+}
+static void counter_latch(Bitu counter) {
+ /* Fill the read_latch of the selected counter with current count */
+ PIT_Block * p=&pit[counter];
+ p->go_read_latch=false;
+
+ //If gate2 is disabled don't update the read_latch
+ if(counter == 2 && !gate2 && p->mode !=1) return;
+
+ double index=PIC_FullIndex()-p->start;
+ switch (p->mode) {
+ case 4: /* Software Triggered Strobe */
+ case 0: /* Interrupt on Terminal Count */
+ /* Counter keeps on counting after passing terminal count */
+ if (index>p->delay) {
+ index-=p->delay;
+ if(p->bcd) {
+ index = fmod(index,(1000.0/PIT_TICK_RATE)*10000.0);
+ p->read_latch = (Bit16u)(9999-index*(PIT_TICK_RATE/1000.0));
+ } else {
+ index = fmod(index,(1000.0/PIT_TICK_RATE)*(double)0x10000);
+ p->read_latch = (Bit16u)(0xffff-index*(PIT_TICK_RATE/1000.0));
+ }
+ } else {
+ p->read_latch=(Bit16u)(p->cntr-index*(PIT_TICK_RATE/1000.0));
+ }
+ break;
+ case 1: // countdown
+ if(p->counting) {
+ if (index>p->delay) { // has timed out
+ p->read_latch = 0xffff; //unconfirmed
+ } else {
+ p->read_latch=(Bit16u)(p->cntr-index*(PIT_TICK_RATE/1000.0));
+ }
+ }
+ break;
+ case 2: /* Rate Generator */
+ index=fmod(index,(double)p->delay);
+ p->read_latch=(Bit16u)(p->cntr - (index/p->delay)*p->cntr);
+ break;
+ case 3: /* Square Wave Rate Generator */
+ index=fmod(index,(double)p->delay);
+ index*=2;
+ if (index>p->delay) index-=p->delay;
+ p->read_latch=(Bit16u)(p->cntr - (index/p->delay)*p->cntr);
+ // In mode 3 it never returns odd numbers LSB (if odd number is written 1 will be
+ // subtracted on first clock and then always 2)
+ // fixes "Corncob 3D"
+ p->read_latch&=0xfffe;
+ break;
+ default:
+ LOG(LOG_PIT,LOG_ERROR)("Illegal Mode %d for reading counter %d",p->mode,counter);
+ p->read_latch=0xffff;
+ break;
+ }
+}
+
+
+static void write_latch(Bitu port,Bitu val,Bitu /*iolen*/) {
+//LOG(LOG_PIT,LOG_ERROR)("port %X write:%X state:%X",port,val,pit[port-0x40].write_state);
+ Bitu counter=port-0x40;
+ PIT_Block * p=&pit[counter];
+ if(p->bcd == true) BIN2BCD(p->write_latch);
+
+ switch (p->write_state) {
+ case 0:
+ p->write_latch = p->write_latch | ((val & 0xff) << 8);
+ p->write_state = 3;
+ break;
+ case 3:
+ p->write_latch = val & 0xff;
+ p->write_state = 0;
+ break;
+ case 1:
+ p->write_latch = val & 0xff;
+ break;
+ case 2:
+ p->write_latch = (val & 0xff) << 8;
+ break;
+ }
+ if (p->bcd==true) BCD2BIN(p->write_latch);
+ if (p->write_state != 0) {
+ if (p->write_latch == 0) {
+ if (p->bcd == false) p->cntr = 0x10000;
+ else p->cntr=9999;
+ } else p->cntr = p->write_latch;
+
+ if ((!p->new_mode) && (p->mode == 2) && (counter == 0)) {
+ // In mode 2 writing another value has no direct effect on the count
+ // until the old one has run out. This might apply to other modes too.
+ // This is not fixed for PIT2 yet!!
+ p->update_count=true;
+ return;
+ }
+ p->start=PIC_FullIndex();
+ p->delay=(1000.0f/((float)PIT_TICK_RATE/(float)p->cntr));
+
+ switch (counter) {
+ case 0x00: /* Timer hooked to IRQ 0 */
+ if (p->new_mode || p->mode == 0 ) {
+ if(p->mode==0) PIC_RemoveEvents(PIT0_Event); // DoWhackaDo demo
+ PIC_AddEvent(PIT0_Event,p->delay);
+ } else LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer set without new control word");
+ LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.4f Hz mode %d",1000.0/p->delay,p->mode);
+ break;
+ case 0x02: /* Timer hooked to PC-Speaker */
+// LOG(LOG_PIT,"PIT 2 Timer at %.3g Hz mode %d",PIT_TICK_RATE/(double)p->cntr,p->mode);
+// PCSPEAKER_SetCounter(p->cntr,p->mode);
+ break;
+ default:
+ LOG(LOG_PIT,LOG_ERROR)("PIT:Illegal timer selected for writing");
+ }
+ p->new_mode=false;
+ }
+}
+
+static Bitu read_latch(Bitu port,Bitu /*iolen*/) {
+//LOG(LOG_PIT,LOG_ERROR)("port read %X",port);
+ Bit32u counter=port-0x40;
+ Bit8u ret=0;
+ if(GCC_UNLIKELY(pit[counter].counterstatus_set)){
+ pit[counter].counterstatus_set = false;
+ latched_timerstatus_locked = false;
+ ret = latched_timerstatus;
+ } else {
+ if (pit[counter].go_read_latch == true)
+ counter_latch(counter);
+
+ if( pit[counter].bcd == true) BIN2BCD(pit[counter].read_latch);
+
+ switch (pit[counter].read_state) {
+ case 0: /* read MSB & return to state 3 */
+ ret=(pit[counter].read_latch >> 8) & 0xff;
+ pit[counter].read_state = 3;
+ pit[counter].go_read_latch = true;
+ break;
+ case 3: /* read LSB followed by MSB */
+ ret = pit[counter].read_latch & 0xff;
+ pit[counter].read_state = 0;
+ break;
+ case 1: /* read LSB */
+ ret = pit[counter].read_latch & 0xff;
+ pit[counter].go_read_latch = true;
+ break;
+ case 2: /* read MSB */
+ ret = (pit[counter].read_latch >> 8) & 0xff;
+ pit[counter].go_read_latch = true;
+ break;
+ default:
+ E_Exit("Timer.cpp: error in readlatch");
+ break;
+ }
+ if( pit[counter].bcd == true) BCD2BIN(pit[counter].read_latch);
+ }
+ return ret;
+}
+
+static void write_p43(Bitu /*port*/,Bitu val,Bitu /*iolen*/) {
+//LOG(LOG_PIT,LOG_ERROR)("port 43 %X",val);
+ Bitu latch=(val >> 6) & 0x03;
+ switch (latch) {
+ case 0:
+ case 1:
+ case 2:
+ if ((val & 0x30) == 0) {
+ /* Counter latch command */
+ counter_latch(latch);
+ } else {
+ pit[latch].bcd = (val&1)>0;
+ if (val & 1) {
+ if(pit[latch].cntr>=9999) pit[latch].cntr=9999;
+ }
+
+ // Timer is being reprogrammed, unlock the status
+ if(pit[latch].counterstatus_set) {
+ pit[latch].counterstatus_set=false;
+ latched_timerstatus_locked=false;
+ }
+ pit[latch].update_count = false;
+ pit[latch].counting = false;
+ pit[latch].read_state = (val >> 4) & 0x03;
+ pit[latch].write_state = (val >> 4) & 0x03;
+ Bit8u mode = (val >> 1) & 0x07;
+ if (mode > 5)
+ mode -= 4; //6,7 become 2 and 3
+
+ /* Don't set it directly so counter_output uses the old mode */
+ /* That's theory. It breaks panic. So set it here again */
+ if(!pit[latch].mode) pit[latch].mode = mode;
+
+ /* If the line goes from low to up => generate irq.
+ * ( BUT needs to stay up until acknowlegded by the cpu!!! therefore: )
+ * If the line goes to low => disable irq.
+ * Mode 0 starts with a low line. (so always disable irq)
+ * Mode 2,3 start with a high line.
+ * counter_output tells if the current counter is high or low
+ * So actually a mode 2 timer enables and disables irq al the time. (not handled) */
+
+ if (latch == 0) {
+ PIC_RemoveEvents(PIT0_Event);
+ if (!counter_output(0) && mode) {
+ PIC_ActivateIRQ(0);
+ //Don't raise instantaniously. (Origamo)
+ if(CPU_Cycles < 25) CPU_Cycles = 25;
+ }
+ if(!mode)
+ PIC_DeActivateIRQ(0);
+ }
+ pit[latch].new_mode = true;
+ pit[latch].mode = mode; //Set the correct mode (here)
+ }
+ break;
+ case 3:
+ if ((val & 0x20)==0) { /* Latch multiple pit counters */
+ if (val & 0x02) counter_latch(0);
+ if (val & 0x04) counter_latch(1);
+ if (val & 0x08) counter_latch(2);
+ }
+ // status and values can be latched simultaneously
+ if ((val & 0x10)==0) { /* Latch status words */
+ // but only 1 status can be latched simultaneously
+ if (val & 0x02) status_latch(0);
+ else if (val & 0x04) status_latch(1);
+ else if (val & 0x08) status_latch(2);
+ }
+ break;
+ }
+}
+
+void TIMER_SetGate2(bool in) {
+ //No changes if gate doesn't change
+ if(gate2 == in) return;
+ Bit8u & mode=pit[2].mode;
+ switch(mode) {
+ case 0:
+ if(in) pit[2].start = PIC_FullIndex();
+ else {
+ //Fill readlatch and store it.
+ counter_latch(2);
+ pit[2].cntr = pit[2].read_latch;
+ }
+ break;
+ case 1:
+ // gate 1 on: reload counter; off: nothing
+ if(in) {
+ pit[2].counting = true;
+ pit[2].start = PIC_FullIndex();
+ }
+ break;
+ case 2:
+ case 3:
+ //If gate is enabled restart counting. If disable store the current read_latch
+ if(in) pit[2].start = PIC_FullIndex();
+ else counter_latch(2);
+ break;
+ case 4:
+ case 5:
+ LOG(LOG_MISC,LOG_WARN)("unsupported gate 2 mode %x",mode);
+ break;
+ }
+ gate2 = in; //Set it here so the counter_latch above works
+}
+
+void x86_timer_write(Bitu port, Bitu val)
+{
+ switch (port)
+ {
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ write_latch(port, val, 1);
+ break;
+ case 0x43:
+ write_p43(port, val, 1);
+ break;
+ }
+}
+Bitu x86_timer_read(Bitu port)
+{
+ switch (port)
+ {
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ return read_latch(port, 1);
+ break;
+ }
+ return 0;
+}
+
+class TIMER:public Module_base{
+//private:
+// IO_ReadHandleObject ReadHandler[4];
+// IO_WriteHandleObject WriteHandler[4];
+public:
+ TIMER(Section* configuration):Module_base(configuration){
+#if 0
+ WriteHandler[0].Install(0x40,write_latch,IO_MB);
+ // WriteHandler[1].Install(0x41,write_latch,IO_MB);
+ WriteHandler[2].Install(0x42,write_latch,IO_MB);
+ WriteHandler[3].Install(0x43,write_p43,IO_MB);
+ ReadHandler[0].Install(0x40,read_latch,IO_MB);
+ ReadHandler[1].Install(0x41,read_latch,IO_MB);
+ ReadHandler[2].Install(0x42,read_latch,IO_MB);
+#endif
+ /* Setup Timer 0 */
+ pit[0].cntr=0x10000;
+ pit[0].write_state = 3;
+ pit[0].read_state = 3;
+ pit[0].read_latch=0;
+ pit[0].write_latch=0;
+ pit[0].mode=3;
+ pit[0].bcd = false;
+ pit[0].go_read_latch = true;
+ pit[0].counterstatus_set = false;
+ pit[0].update_count = false;
+
+ pit[1].bcd = false;
+ pit[1].write_state = 1;
+ pit[1].read_state = 1;
+ pit[1].go_read_latch = true;
+ pit[1].cntr = 18;
+ pit[1].mode = 2;
+ pit[1].write_state = 3;
+ pit[1].counterstatus_set = false;
+
+ pit[2].read_latch=1320; /* MadTv1 */
+ pit[2].write_state = 3; /* Chuck Yeager */
+ pit[2].read_state = 3;
+ pit[2].mode=3;
+ pit[2].bcd=false;
+ pit[2].cntr=1320;
+ pit[2].go_read_latch=true;
+ pit[2].counterstatus_set = false;
+ pit[2].counting = false;
+
+ pit[0].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[0].cntr));
+ pit[1].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[1].cntr));
+ pit[2].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[2].cntr));
+
+ latched_timerstatus_locked=false;
+ gate2 = false;
+ PIC_AddEvent(PIT0_Event,pit[0].delay);
+ }
+ ~TIMER(){
+ PIC_RemoveEvents(PIT0_Event);
+ }
+};
+static TIMER* test;
+
+void TIMER_Destroy(Section*){
+ delete test;
+}
+void TIMER_Init(Section* sec) {
+ test = new TIMER(sec);
+ sec->AddDestroyFunction(&TIMER_Destroy);
+}
--- /dev/null
+/*
+ * Copyright (C) 2002-2010 The DOSBox Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef DOSBOX_TIMER_H
+#define DOSBOX_TIMER_H
+
+/* underlying clock rate in HZ */
+//#include <SDL.h>
+
+#define PIT_TICK_RATE 1193182
+
+//#define GetTicks() SDL_GetTicks()
+
+typedef void (*TIMER_TickHandler)(void);
+
+/* Register a function that gets called everytime if 1 or more ticks pass */
+void TIMER_AddTickHandler(TIMER_TickHandler handler);
+void TIMER_DelTickHandler(TIMER_TickHandler handler);
+
+/* This will add 1 milliscond to all timers */
+void TIMER_AddTick(void);
+
+#endif
void x86_bridge_reset(void);
void x86_bridge_free(void);
void x86_bridge_rethink(void);
+void x86_bridge_sync_change(void);
#define X86_STATE_INACTIVE 0
#define X86_STATE_STOP 1
#include "dosbox/paging.h"
#include "dosbox/setup.h"
#include "dosbox/cpu.h"
+#include "dosbox/pic.h"
+#include "dosbox/timer.h"
typedef Bits(CPU_Decoder)(void);
extern CPU_Decoder *cpudecoder;
extern Bit32s CPU_Cycles;
void x86_doirq(uint8_t irqnum);
static frame_time_t last_cycles;
-#define DEFAULT_X86_INSTRUCTION_COUNT 40
+#define DEFAULT_X86_INSTRUCTION_COUNT 120
static int x86_instruction_count;
static bool x86_turbo_allowed;
static bool x86_turbo_enabled;
bool x86_turbo_on;
bool x86_cpu_active;
-void CPU_Init(Section*);
+void CPU_Init(Section*, int, int);
void CPU_ShutDown(Section*);
void CPU_JMP(bool use32, Bitu selector, Bitu offset, Bitu oldeip);
void PAGING_Init(Section * sec);
void CMOS_Destroy(Section* sec);
void PIC_Init(Section* sec);
void PIC_Destroy(Section* sec);
+void TIMER_Destroy(Section*);
+void TIMER_Init(Section* sec);
static Section_prop *dosbox_sec;
Bitu x86_in_keyboard(Bitu port);
void x86_out_keyboard(Bitu port, Bitu val);
Bitu cmos_readreg(Bitu port, Bitu iolen);
void x86_pic_write(Bitu port, Bitu val);
Bitu x86_pic_read(Bitu port);
+void x86_timer_write(Bitu port, Bitu val);
+Bitu x86_timer_read(Bitu port);
void PIC_ActivateIRQ(Bitu irq);
void PIC_DeActivateIRQ(Bitu irq);
void PIC_runIRQs(void);
void FPU_Init(Section*);
Bit8u *x86_cmos_regs(Bit8u *regs);
void MEM_SetVGAHandler(void);
+Bit32s ticksDone;
+Bit32u ticksScheduled;
HostPt mono_start, mono_end, color_start, color_end;
int x86_memsize;
int x86_biosstart;
uaecptr baseaddress;
int pc_maxram;
uae_u8 *pc_ram;
+ uae_u8 *pc_rom;
uae_u8 *io_ports;
uae_u8 *amiga_io;
bool x86_reset;
int bios_size;
int settings;
int dosbox_cpu;
+ int dosbox_cpu_arch;
bool x86_reset_requested;
struct zfile *cmosfile;
uae_u8 cmosregs[3 * 0x40];
+ uae_u8 vlsi_regs[0x100];
+ int a2386_default_video;
int cmossize;
int scamp_idx1, scamp_idx2;
+ uae_u8 rombank[1024 * 1024 / 4096];
+ float dosbox_vpos_tick;
+ float dosbox_tick_vpos_cnt;
struct romconfig *rc;
};
static int x86_found;
static void reset_dosbox_cpu(void)
{
+ struct x86_bridge *xb = bridges[0];
+
CPU_ShutDown(dosbox_sec);
- CPU_Init(dosbox_sec);
+ CPU_Init(dosbox_sec, xb->dosbox_cpu, xb->dosbox_cpu_arch);
CPU_JMP(false, 0xffff, 0, 0);
}
struct x86_bridge *xb = bridges[0];
uint8_t v = 0;
- if (!(xb->settings & (1 << 14)))
- v |= 0x40;
- if (!(xb->settings & (1 << 15)))
- v |= 0x80; // key lock off
+ if (xb->type >= TYPE_2286) {
+ if (xb->pc_maxbaseram > 512 * 1024)
+ v |= 0x20;
+ }
+
+ if (xb->type == TYPE_2386) {
+ // A2386 = software controlled
+ if (xb->a2386_default_video)
+ v |= 0x40;
+ } else {
+ // Others have default video jumper
+ if (!(xb->settings & (1 << 14))) {
+ // default video mde, 0 = cga, 1 = mda
+ v |= 0x40;
+ }
+ }
+
+ if (!(xb->settings & (1 << 15))) {
+ // key lock state: 0 = on, 1 = off
+ v |= 0x80;
+ }
return v;
}
break;
case IO_A2386_CONFIG:
write_log(_T("A2386 CONFIG BYTE %02x\n"), v);
+ if (v == 8 || v == 9) {
+ xb->a2386_default_video = v & 1;
+ write_log(_T("A2386 Default mode = %s\n"), xb->a2386_default_video ? _T("MDA") : _T("CGA"));
+ }
break;
default:
static bool floppy_valid_rate(struct floppy_reserved *fr)
{
+ struct x86_bridge *xb = bridges[0];
+ // A2386 BIOS sets 720k data rate for both 720k and 1.4M drives
+ // probably because it thinks Amiga half-speed drive is connected?
+ if (xb->type == TYPE_2386 && fr->rate == 0 && floppy_rate == 2)
+ return true;
return fr->rate == floppy_rate || floppy_rate < 0;
}
floppy_delay_hsync = 20;
}
#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);
+ write_log(_T("DPC=%02x: Motormask %02x sel=%d dmaen=%d reset=%d\n"), v, (v >> 4) & 15, v & 3, (v & 8) ? 1 : 0, (v & 4) ? 0 : 1);
#endif
#ifdef DRIVESOUND
for (int i = 0; i < 2; i++) {
floppy_rate = -1;
}
break;
+ default:
+ write_log(_T("Unknown FDC %04x write %02x\n"), portnum, v);
+ break;
}
#if FLOPPY_IO_DEBUG
write_log(_T("out floppy port %04x %02x\n"), portnum, v);
#endif
}
+
static uae_u8 infloppy(struct x86_bridge *xb, int portnum)
{
uae_u8 v = 0;
v = 0x80;
}
break;
+ default:
+ write_log(_T("Unknown FDC %04x read\n"), portnum);
+ break;
}
#if FLOPPY_IO_DEBUG
write_log(_T("in floppy port %04x %02x\n"), portnum, v);
static void set_pc_io_access(struct x86_bridge *xb, uaecptr portnum, bool write)
{
+ uae_u8 mode_register = xb->amiga_io[IO_MODE_REGISTER];
if (write && portnum >= 0x3b0 && portnum < 0x3bf) {
// mono crt
- if (xb->amiga_io[IO_MODE_REGISTER] & 8)
+ if (mode_register & 8)
set_interrupt(xb, 2);
} else if (write && portnum >= 0x3d0 && portnum < 0x3df) {
// color crt
- if (xb->amiga_io[IO_MODE_REGISTER] & 16)
+ if (mode_register & 16)
set_interrupt(xb, 3);
} else if (portnum >= 0x37a && portnum < 0x37b) {
// LPT1
return true;
}
+static uae_u8 vlsi_in(struct x86_bridge *xb, int portnum)
+{
+ uae_u8 v = 0;
+ switch(portnum)
+ {
+ case 0xed:
+ v = xb->vlsi_regs[xb->scamp_idx2];
+ break;
+ }
+ //write_log(_T("VLSI_IN %02x = %02x\n"), portnum, v);
+ return v;
+}
+
+static void vlsi_reg_out(struct x86_bridge *xb, int reg, uae_u8 v)
+{
+ uae_u32 shadow_start = 0;
+ uae_u32 shadow_size = 0;
+
+ switch(reg)
+ {
+ case 0x1d:
+ x86_cmos_bank = (v & 0x20) ? 1 : 0;
+ break;
+ case 0x0e: // ABAX
+ shadow_size = 0x8000;
+ shadow_start = 0xa0000;
+ break;
+ case 0x0f: // CAXS
+ shadow_size = 0x4000;
+ shadow_start = 0xc0000;
+ break;
+ case 0x10: // DAXS
+ shadow_size = 0x4000;
+ shadow_start = 0xd0000;
+ break;
+ case 0x11: // FEAXS
+ shadow_size = 0x4000;
+ shadow_start = 0xe0000;
+ break;
+ }
+ if (shadow_size) {
+ for (int i = 0; i < 4; i++) {
+ int state = (v >> (i * 2)) & 3;
+ write_log(_T("%06x - %06x : shadow status=%d\n"), shadow_start, shadow_start + shadow_size - 1, state);
+ shadow_start += shadow_size;
+ }
+
+ }
+}
+
+
+static void vlsi_out(struct x86_bridge *xb, int portnum, uae_u8 v)
+{
+ switch (portnum)
+ {
+ case 0xe8:
+ xb->scamp_idx1 = v;
+ break;
+ case 0xec:
+ xb->scamp_idx2 = v;
+ break;
+ case 0xed:
+ xb->vlsi_regs[xb->scamp_idx2] = v;
+ vlsi_reg_out(xb, xb->scamp_idx2, v);
+ break;
+ }
+ //write_log(_T("VLSI_OUT %02x = %02x\n"), portnum, v);
+}
+
+
void portout(uint16_t portnum, uint8_t v)
{
struct x86_bridge *xb = bridges[0];
case 0x41:
case 0x42:
case 0x43:
- out8253(portnum, v);
+ if (xb->dosbox_cpu)
+ x86_timer_write(portnum, v);
+ else
+ out8253(portnum, v);
break;
case 0x80:
case 0x81:
// A2386SX only
case 0xe8:
- xb->scamp_idx1 = v;
- break;
+ case 0xe9:
+ case 0xea:
+ case 0xeb:
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;
- }
+ case 0xee:
+ case 0xef:
+ case 0xf0:
+ case 0xf1:
+ case 0xf4:
+ case 0xf5:
+ case 0xf8:
+ case 0xf9:
+ case 0xfa:
+ case 0xfb:
+ case 0xfc:
+ case 0xfe:
+ if (xb->type >= TYPE_2386)
+ vlsi_out(xb, portnum, v);
break;
// floppy
case 0x3f3:
case 0x3f4:
case 0x3f5:
- case 0x3f6:
case 0x3f7:
outfloppy(xb, portnum, v);
break;
case 0x175:
case 0x176:
case 0x177:
+ case 0x376:
x86_ide_hd_put(portnum, v, 0);
break;
// at ide 0
case 0x1f5:
case 0x1f6:
case 0x1f7:
+ case 0x3f6:
x86_ide_hd_put(portnum, v, 0);
break;
case 0x170:
case 0x1f0:
case 0x300:
- x86_ide_hd_put(portnum, value >> 16, 1);
x86_ide_hd_put(portnum, value, 1);
+ x86_ide_hd_put(portnum, value >> 16, 1);
break;
default:
write_log(_T("portout32 %08x %08x\n"), portnum, value);
case 0x41:
case 0x42:
case 0x43:
- v = in8253(portnum);
+ if (xb->dosbox_cpu)
+ v = x86_timer_read(portnum);
+ else
+ v = in8253(portnum);
break;
case 0x80:
}
break;
+ // A2386SX only
+ case 0xe8:
+ case 0xe9:
+ case 0xea:
+ case 0xeb:
+ case 0xec:
+ case 0xed:
+ case 0xee:
+ case 0xef:
+ case 0xf0:
+ case 0xf1:
+ case 0xf4:
+ case 0xf5:
+ case 0xf8:
+ case 0xf9:
+ case 0xfa:
+ case 0xfb:
+ case 0xfc:
+ case 0xfe:
+ if (xb->type >= TYPE_2386)
+ v = vlsi_in(xb, portnum);
+ break;
+
// floppy
case 0x3f0:
case 0x3f1:
case 0x3f3:
case 0x3f4:
case 0x3f5:
- case 0x3f6:
case 0x3f7:
v = infloppy(xb, portnum);
break;
case 0x60:
- //write_log(_T("PC read keycode %02x\n"), v);
if (xb->type >= TYPE_2286) {
v = x86_in_keyboard(0x60);
+ //write_log(_T("PC read keycode %02x\n"), v);
}
break;
case 0x61:
}
break;
- case 0xed:
- if (xb->scamp_idx2 == 0x1d) {
- v = x86_cmos_bank ? 0x20 : 0x00;
- }
- break;
-
// at ide 1
case 0x170:
case 0x171:
case 0x175:
case 0x176:
case 0x177:
+ case 0x376:
v = x86_ide_hd_get(portnum, 0);
break;
// at ide 0
case 0x1f5:
case 0x1f6:
case 0x1f7:
+ case 0x3f6:
v = x86_ide_hd_get(portnum, 0);
break;
case 0x170:
case 0x1f0:
case 0x300:
- v = x86_ide_hd_get(portnum, 1) << 16;
- v |= x86_ide_hd_get(portnum, 1);
+ v = x86_ide_hd_get(portnum, 1) << 0;
+ v |= x86_ide_hd_get(portnum, 1) << 16;
break;
default:
write_log(_T("portin32 %08x\n"), portnum);
static uaecptr get_x86_address(struct x86_bridge *xb, uaecptr addr, int *mode)
{
addr -= xb->baseaddress;
+ if (!xb->baseaddress || addr >= 0x80000) {
+ *mode = -1;
+ return 0;
+ }
*mode = addr >> 17;
addr &= 0x1ffff;
if (addr < 0x10000) {
write_log(_T("pci_bridge_wput %08x (%08x,%d) %04x PC=%08x\n"), addr - xb->baseaddress, a, mode, b & 0xffff, M68K_GETPC);
#endif
- if (a >= 0x100000 - xb->bios_size || mode < 0)
+ if (a >= 0x100000 || mode < 0)
+ return;
+ if (xb->rombank[a / 4096])
return;
if (mode == ACCESS_MODE_IO) {
int mode;
uaecptr a = get_x86_address(xb, addr, &mode);
- if (a >= 0x100000 - xb->bios_size || mode < 0)
+ if (a >= 0x100000 || mode < 0)
+ return;
+ if (xb->rombank[a / 4096])
return;
#if X86_DEBUG_BRIDGE > 1
}
CPU_ShutDown(dosbox_sec);
CMOS_Destroy(dosbox_sec);
+ TIMER_Destroy(dosbox_sec);
PIC_Destroy(dosbox_sec);
MEM_ShutDown(dosbox_sec);
delete dosbox_sec;
xfree(xb->amiga_io);
xfree(xb->io_ports);
xfree(xb->pc_ram);
+ xfree(xb->pc_rom);
zfile_fclose(xb->cmosfile);
bridges[i] = NULL;
}
}
}
-
static void x86_cpu_execute(int cnt)
{
struct x86_bridge *xb = bridges[0];
xb->x86_reset_requested = false;
reset_x86_cpu(xb);
}
- CPU_Cycles = cnt;
- (*cpudecoder)();
+ Bit32s old_cpu_cycles = CPU_Cycles;
+ if (CPU_Cycles > cnt)
+ CPU_Cycles = cnt;
+ if (PIC_RunQueue()) {
+ (*cpudecoder)();
+ }
+ CPU_Cycles = old_cpu_cycles -= cnt;
+ if (CPU_Cycles < 0)
+ CPU_Cycles = 0;
check_x86_irq();
} else {
exec86(cnt);
}
}
+void x86_bridge_sync_change(void)
+{
+ struct x86_bridge *xb = bridges[0];
+ if (!xb)
+ return;
+
+ xb->dosbox_vpos_tick = maxvpos * vblank_hz / 1000;
+ if (xb->dosbox_vpos_tick >= xb->dosbox_vpos_tick)
+ xb->dosbox_tick_vpos_cnt -= xb->dosbox_vpos_tick;
+}
+
void x86_bridge_hsync(void)
{
struct x86_bridge *xb = bridges[0];
check_floppy_delay();
- for (int i = 0; i < 3; i++) {
- x86_cpu_execute(x86_instruction_count);
- timing(maxhpos / 3);
+ if (!xb->x86_reset) {
+ if (xb->dosbox_cpu) {
+ xb->dosbox_tick_vpos_cnt++;
+ if (xb->dosbox_tick_vpos_cnt >= xb->dosbox_vpos_tick) {
+ TIMER_AddTick();
+ xb->dosbox_tick_vpos_cnt -= xb->dosbox_vpos_tick;
+ }
+ x86_cpu_execute(x86_instruction_count);
+ } else {
+ for (int i = 0; i < 3; i++) {
+ x86_cpu_execute(x86_instruction_count / 3);
+ timing(maxhpos / 3);
+ }
+ }
}
if (currprefs.x86_speed_throttle != changed_prefs.x86_speed_throttle) {
}
}
+static void setrombank(struct x86_bridge *xb, int start, int len)
+{
+ while (len > 0) {
+ xb->rombank[start / 4096] = 1;
+ start += 4096;
+ len -= 4096;
+ }
+}
+
static void bridge_reset(struct x86_bridge *xb)
{
- uae_u8 *temp[2];
xb->x86_reset = true;
xb->configured = 0;
xb->amiga_forced_interrupts = false;
x86_instruction_count = DEFAULT_X86_INSTRUCTION_COUNT;
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);
+ memset(xb->rombank, 0, sizeof xb->rombank);
+
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]);
+ if (x86_xrom_end[i] - x86_xrom_start[i] > 0) {
+ memcpy(xb->pc_ram + x86_xrom_start[i], xb->pc_rom + x86_xrom_start[i], x86_xrom_end[i] - x86_xrom_start[i]);
+ setrombank(xb, x86_xrom_start[i], x86_xrom_end[i] - x86_xrom_start[i]);
}
}
+ memcpy(xb->pc_ram + 0x100000 - xb->bios_size, xb->pc_rom + 0x100000 - xb->bios_size, xb->bios_size);
+ setrombank(xb, 0x100000 - xb->bios_size, xb->bios_size);
+
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;
+ memset(xb->vlsi_regs, 0, sizeof xb->vlsi_regs);
if (xb->type >= TYPE_2286) {
int sel1 = (xb->settings >> 10) & 1;
xb->amiga_io[IO_MODE_REGISTER] |= sel1 << 5;
xb->amiga_io[IO_MODE_REGISTER] |= sel2 << 6;
}
+ if (xb->type == TYPE_2386)
+ x86_turbo_allowed = true;
+ x86_bridge_sync_change();
inittiming();
floppy_hardreset();
}
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);
+ x86_xrom_end[1] += zfile_fread(xb->pc_rom + x86_xrom_start[1], 1, 65536, zf);
zfile_fclose(zf);
x86_xrom_end[1] += 4095;
x86_xrom_end[1] &= ~4095;
+ memcpy(xb->pc_ram + x86_xrom_start[1], xb->pc_rom + x86_xrom_start[1], x86_xrom_end[1] - x86_xrom_start[1]);
+ setrombank(xb, x86_xrom_start[1], x86_xrom_end[1] - x86_xrom_start[1]);
}
if (xb->dosbox_cpu) {
MEM_ShutDown(dosbox_sec);
}
}
-void x86_xt_ide_bios(struct zfile *z)
+void x86_xt_ide_bios(struct zfile *z, struct romconfig *rc)
{
struct x86_bridge *xb = bridges[0];
+ uae_u32 addr = 0;
if (!xb || !z)
return;
- x86_xrom_start[0] = 0xec000;
+ switch (rc->device_settings)
+ {
+ case 0:
+ addr = 0xcc000;
+ break;
+ case 1:
+ addr = 0xdc000;
+ break;
+ case 2:
+ default:
+ addr = 0xec000;
+ break;
+ }
+ x86_xrom_start[0] = addr;
x86_xrom_end[0] = x86_xrom_start[0] + 0x4000;
- zfile_fread(xb->pc_ram + x86_xrom_start[0], 1, 32768, z);
+ zfile_fread(xb->pc_rom + x86_xrom_start[0], 1, 32768, z);
+ memcpy(xb->pc_ram + x86_xrom_start[0], xb->pc_rom + x86_xrom_start[0], x86_xrom_end[0] - x86_xrom_start[0]);
+ setrombank(xb, x86_xrom_start[0], x86_xrom_end[0] - x86_xrom_start[0]);
if (xb->dosbox_cpu) {
MEM_ShutDown(dosbox_sec);
MEM_Init(dosbox_sec);
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 };
-addrbank *x86_bridge_init(struct romconfig *rc, int type)
+addrbank *x86_bridge_init(struct romconfig *rc, uae_u32 romtype, int type)
{
struct x86_bridge *xb = x86_bridge_alloc();
const uae_u8 *ac;
xb->settings = rc->device_settings;
if (xb->type >= TYPE_2286) {
xb->dosbox_cpu = ((xb->settings >> 19) & 3) + 1;
+ xb->dosbox_cpu_arch = (xb->settings >> 23) & 7;
xb->settings |= 0xff;
ac = xb->type >= TYPE_2386 ? a2386_autoconfig : a1060_autoconfig;
xb->pc_maxram = (1024 * 1024) << ((xb->settings >> 16) & 7);
xb->bios_size = 65536;
} else {
xb->dosbox_cpu = (xb->settings >> 19) & 7;
+ xb->dosbox_cpu_arch = (xb->settings >> 23) & 7;
ac = a1060_autoconfig;
xb->pc_maxram = 1 * 1024 * 1024;
xb->bios_size = 32768;
}
xb->pc_ram = xcalloc(uae_u8, xb->pc_maxram + 1 * 1024 * 1024);
+ xb->pc_rom = xcalloc(uae_u8, 0x100000);
x86_memsize = xb->pc_maxram;
mono_start = xb->pc_ram + 0xb0000;
mono_end = xb->pc_ram + 0xb2000;
MemBase = xb->pc_ram;
if (xb->dosbox_cpu) {
+ ticksDone = 0;
+ ticksScheduled = 0;
x86_fpu_enabled = (xb->settings >> 22) & 1;
dosbox_sec = new Section_prop("dummy");
MEM_Init(dosbox_sec);
PAGING_Init(dosbox_sec);
CMOS_Init(dosbox_sec, xb->type == TYPE_2386 ? 0x7f : 0x3f);
PIC_Init(dosbox_sec);
+ TIMER_Init(dosbox_sec);
FPU_Init(dosbox_sec);
if (xb->type >= TYPE_2286) {
xb->cmossize = xb->type == TYPE_2386 ? 192 : 64;
}
}
if (ISVGA()) {
- MEM_SetVGAHandler();
+ if (xb->dosbox_cpu) {
+ MEM_SetVGAHandler();
+ }
load_vga_bios();
}
bridge_reset(xb);
// load bios
- if (!load_rom_rc(rc, NULL, xb->bios_size, 0, xb->pc_ram + 0x100000 - xb->bios_size, xb->bios_size, LOADROM_FILL)) {
+ if (!load_rom_rc(rc, romtype, xb->bios_size, 0, xb->pc_rom + 0x100000 - xb->bios_size, xb->bios_size, LOADROM_FILL)) {
error_log(_T("Bridgeboard BIOS failed to load"));
x86_bridge_free();
return &expamem_null;
}
+ memcpy(xb->pc_ram + 0x100000 - xb->bios_size, xb->pc_rom + 0x100000 - xb->bios_size, xb->bios_size);
+ setrombank(xb, 0x100000 - xb->bios_size, xb->bios_size);
xb->bank = &x86_bridge_bank;
for (int i = 0; i < 16; i++) {
addrbank *a1060_init(struct romconfig *rc)
{
- return x86_bridge_init(rc, TYPE_SIDECAR);
+ return x86_bridge_init(rc, ROMTYPE_A1060, TYPE_SIDECAR);
}
addrbank *a2088xt_init(struct romconfig *rc)
{
- return x86_bridge_init(rc, TYPE_2088);
+ return x86_bridge_init(rc, ROMTYPE_A2088, TYPE_2088);
}
addrbank *a2088t_init(struct romconfig *rc)
{
- return x86_bridge_init(rc, TYPE_2088T);
+ return x86_bridge_init(rc, ROMTYPE_A2088T, TYPE_2088T);
}
addrbank *a2286_init(struct romconfig *rc)
{
- return x86_bridge_init(rc, TYPE_2286);
+ return x86_bridge_init(rc, ROMTYPE_A2286, TYPE_2286);
}
addrbank *a2386_init(struct romconfig *rc)
{
- return x86_bridge_init(rc, TYPE_2386);
+ return x86_bridge_init(rc, ROMTYPE_A2386, TYPE_2386);
}
/* dosbox cpu core support stuff */
-Bit32s ticksDone;
-Bit32u ticksScheduled;
-
void IO_WriteB(Bitu port, Bitu val)
{
portout(port, val);
return portin32(port);
}
-void TIMER_SetGate2(bool v)
-{
- write_log(_T("void TIMER_SetGate2(%d)!\n"), v);
-}
-
Bits CPU_Core_Prefetch_Run(void)
{
return 0;