/* * Copyright (C) 2002-2003 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 Library 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. */ #include "dosbox.h" #include "cpu.h" #include "memory.h" #include "debug.h" #include "keyboard.h" #include "setup.h" //Regs regs; Flag_Info flags; CPU_Regs cpu_regs; Segment Segs[6]; Bits CPU_Cycles=0; Bits CPU_CycleLeft=0; Bits CPU_CycleMax=1500; CPU_Decoder * cpudecoder; static void CPU_CycleIncrease(void) { Bitu old_cycles=CPU_CycleMax; CPU_CycleMax=(Bitu)(CPU_CycleMax*1.2); CPU_CycleLeft=0;CPU_Cycles=0; if (CPU_CycleMax==old_cycles) CPU_CycleMax++; LOG_MSG("CPU:%d cycles",CPU_CycleMax); } static void CPU_CycleDecrease(void) { CPU_CycleMax=(Bitu)(CPU_CycleMax/1.2); CPU_CycleLeft=0;CPU_Cycles=0; if (!CPU_CycleMax) CPU_CycleMax=1; LOG_MSG("CPU:%d cycles",CPU_CycleMax); } Bit8u lastint; void Interrupt(Bit8u num) { lastint=num; //DEBUG THINGIE to check fucked ints switch (num) { case 0x00: LOG(LOG_CPU,"Divide Error"); break; case 0x06: break; case 0x07: LOG(LOG_FPU,"Co Processor Exception"); break; case 0x08: case 0x09: case 0x10: case 0x11: case 0x12: case 0x13: case 0x15: case 0x16: case 0x17: case 0x1A: case 0x1C: case 0x21: case 0x2a: case 0x2f: case 0x33: case 0x67: case 0x74: break; case 0xcd: #if C_HEAVY_DEBUG LOG(LOG_CPU|LOG_ERROR,"Call to interrupt 0xCD this is BAD"); DEBUG_HeavyWriteLogInstruction(); #endif E_Exit("Call to interrupt 0xCD this is BAD"); case 0x03: #if C_DEBUG if (DEBUG_Breakpoint()) return; #endif break; case 0x05: LOG(LOG_CPU,"CPU:Out Of Bounds interrupt"); break; default: // LOG_WARN("Call to unsupported INT %02X call %02X",num,reg_ah); break; }; /* Check for 16-bit or 32-bit and then setup everything for the interrupt to start */ Bit16u pflags; pflags= (get_CF() << 0) | (get_PF() << 2) | (get_AF() << 4) | (get_ZF() << 6) | (get_SF() << 7) | (flags.tf << 8) | (flags.intf << 9) | (flags.df << 10) | (get_OF() << 11) | (flags.io << 12) | (flags.nt <<14); flags.intf=false; flags.tf=false; /* Save everything on a 16-bit stack */ reg_sp-=2; mem_writew(SegPhys(ss)+reg_sp,pflags); reg_sp-=2; mem_writew(SegPhys(ss)+reg_sp,SegValue(cs)); reg_sp-=2; mem_writew(SegPhys(ss)+reg_sp,reg_ip); /* Get the new CS:IP from vector table */ Bit16u newip=mem_readw(num << 2); Bit16u newcs=mem_readw((num <<2)+2); SegSet16(cs,newcs); reg_ip=newip; } void CPU_Real_16_Slow_Start(void); void SetCPU16bit() { CPU_Real_16_Slow_Start(); } void CPU_Init(Section* sec) { Section_prop * section=static_cast(sec); reg_eax=0; reg_ebx=0; reg_ecx=0; reg_edx=0; reg_edi=0; reg_esi=0; reg_ebp=0; reg_esp=0; SegSet16(cs,0); SegSet16(ds,0); SegSet16(es,0); SegSet16(fs,0); SegSet16(gs,0); SegSet16(ss,0); reg_eip=0; flags.type=t_UNKNOWN; flags.af=0; flags.cf=0; flags.cf=0; flags.sf=0; flags.zf=0; flags.intf=true; flags.nt=0; flags.io=0; SetCPU16bit(); KEYBOARD_AddEvent(KBD_f11,KBD_MOD_CTRL,CPU_CycleDecrease); KEYBOARD_AddEvent(KBD_f12,KBD_MOD_CTRL,CPU_CycleIncrease); CPU_Cycles=0; CPU_CycleMax=section->Get_int("cycles");; if (!CPU_CycleMax) CPU_CycleMax=1500; CPU_CycleLeft=0; MSG_Add("CPU_CONFIGFILE_HELP","The amount of cycles to execute each loop. Lowering this setting will slowdown dosbox\n"); }