mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-05-09 03:41:10 +08:00
PC-98: IRQ 0 on PC-98 works differently than IBM PC. There is a timer interval system in place to fire INT 07h on timeout, set by INT 1Ch AH=02h. PC-98 also leaves the timer off by default otherwise.
This commit is contained in:
parent
5a42f58b50
commit
19ca5c1c3c
@ -2635,16 +2635,44 @@ static Bitu INT1B_PC98_Handler(void) {
|
|||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PC98_Interval_Timer_Continue(void) {
|
||||||
|
/* assume: interrupts are disabled */
|
||||||
|
IO_WriteB(0x71,0x00);
|
||||||
|
// TODO: What time interval is this supposed to be?
|
||||||
|
if (PIT_TICK_RATE == PIT_TICK_RATE_PC98_8MHZ)
|
||||||
|
IO_WriteB(0x71,0x4E);
|
||||||
|
else
|
||||||
|
IO_WriteB(0x71,0x60);
|
||||||
|
|
||||||
|
PIC_SetIRQMask(0,false);
|
||||||
|
}
|
||||||
|
|
||||||
static Bitu INT1C_PC98_Handler(void) {
|
static Bitu INT1C_PC98_Handler(void) {
|
||||||
LOG_MSG("PC-98 INT 1Ch unknown call AX=%04X BX=%04X CX=%04X DX=%04X SI=%04X DI=%04X DS=%04X ES=%04X",
|
if (reg_ah == 0x02) { /* set interval timer (single event) */
|
||||||
reg_ax,
|
/* es:bx = interrupt handler to execute
|
||||||
reg_bx,
|
* cx = timer interval in ticks (FIXME: what units of time?) */
|
||||||
reg_cx,
|
mem_writew(0x1C,reg_bx);
|
||||||
reg_dx,
|
mem_writew(0x1E,SegValue(es));
|
||||||
reg_si,
|
mem_writew(0x58A,reg_cx);
|
||||||
reg_di,
|
|
||||||
SegValue(ds),
|
IO_WriteB(0x77,0x36); /* mode 3, binary, low-byte high-byte 16-bit counter */
|
||||||
SegValue(es));
|
|
||||||
|
PC98_Interval_Timer_Continue();
|
||||||
|
}
|
||||||
|
else if (reg_ah == 0x03) { /* continue interval timer */
|
||||||
|
PC98_Interval_Timer_Continue();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_MSG("PC-98 INT 1Ch unknown call AX=%04X BX=%04X CX=%04X DX=%04X SI=%04X DI=%04X DS=%04X ES=%04X",
|
||||||
|
reg_ax,
|
||||||
|
reg_bx,
|
||||||
|
reg_cx,
|
||||||
|
reg_dx,
|
||||||
|
reg_si,
|
||||||
|
reg_di,
|
||||||
|
SegValue(ds),
|
||||||
|
SegValue(es));
|
||||||
|
}
|
||||||
|
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
@ -2788,6 +2816,29 @@ void BIOS_KEYBOARD_SetLEDs(Bitu state) {
|
|||||||
KEYBOARD_SetLEDs(state);
|
KEYBOARD_SetLEDs(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PC-98 IRQ 0 system timer */
|
||||||
|
static Bitu INT8_PC98_Handler(void) {
|
||||||
|
Bit16u counter = mem_readw(0x58A) - 1;
|
||||||
|
mem_writew(0x58A,counter);
|
||||||
|
|
||||||
|
if (counter == 0) {
|
||||||
|
/* mask IRQ 0 */
|
||||||
|
IO_WriteB(0x02,IO_ReadB(0x02) | 0x01);
|
||||||
|
/* ack IRQ 0 */
|
||||||
|
IO_WriteB(0x00,0x20);
|
||||||
|
/* INT 07h */
|
||||||
|
CPU_Interrupt(7,CPU_INT_SOFTWARE,reg_eip);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* ack IRQ 0 */
|
||||||
|
IO_WriteB(0x00,0x20);
|
||||||
|
/* make sure it continues ticking */
|
||||||
|
PC98_Interval_Timer_Continue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return CBRET_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static Bitu INT8_Handler(void) {
|
static Bitu INT8_Handler(void) {
|
||||||
/* Increase the bios tick counter */
|
/* Increase the bios tick counter */
|
||||||
Bit32u value = mem_readd(BIOS_TIMER) + 1;
|
Bit32u value = mem_readd(BIOS_TIMER) + 1;
|
||||||
@ -4294,6 +4345,8 @@ private:
|
|||||||
|
|
||||||
if (cpu.pmode) E_Exit("BIOS error: POST function called while in protected/vm86 mode");
|
if (cpu.pmode) E_Exit("BIOS error: POST function called while in protected/vm86 mode");
|
||||||
|
|
||||||
|
CPU_CLI();
|
||||||
|
|
||||||
/* we need A20 enabled for BIOS boot-up */
|
/* we need A20 enabled for BIOS boot-up */
|
||||||
void A20Gate_OverrideOn(Section *sec);
|
void A20Gate_OverrideOn(Section *sec);
|
||||||
void MEM_A20_Enable(bool enabled);
|
void MEM_A20_Enable(bool enabled);
|
||||||
@ -4362,6 +4415,9 @@ private:
|
|||||||
callback[18].Uninstall();
|
callback[18].Uninstall();
|
||||||
callback[18].Install(&INTGEN_PC98_Handler,CB_IRET,"Int stub ???");
|
callback[18].Install(&INTGEN_PC98_Handler,CB_IRET,"Int stub ???");
|
||||||
for (unsigned int i=0x40;i < 0x100;i++) RealSetVec(i,callback[18].Get_RealPointer());
|
for (unsigned int i=0x40;i < 0x100;i++) RealSetVec(i,callback[18].Get_RealPointer());
|
||||||
|
|
||||||
|
/* need handler at INT 07h */
|
||||||
|
real_writed(0,0x07*4,BIOS_DEFAULT_HANDLER_LOCATION);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Clear the vector table */
|
/* Clear the vector table */
|
||||||
@ -4381,7 +4437,6 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (IS_PC98_ARCH) {
|
if (IS_PC98_ARCH) {
|
||||||
CALLBACK_Setup(call_irq0,INT8_Handler,CB_IRET_EOI_PIC1,Real2Phys(BIOS_DEFAULT_IRQ0_LOCATION),"IRQ 0 Clock");
|
|
||||||
CALLBACK_Setup(call_irq07default,NULL,CB_IRET_EOI_PIC1,Real2Phys(BIOS_DEFAULT_IRQ07_DEF_LOCATION),"bios irq 0-7 default handler");
|
CALLBACK_Setup(call_irq07default,NULL,CB_IRET_EOI_PIC1,Real2Phys(BIOS_DEFAULT_IRQ07_DEF_LOCATION),"bios irq 0-7 default handler");
|
||||||
CALLBACK_Setup(call_irq815default,NULL,CB_IRET_EOI_PIC2,Real2Phys(BIOS_DEFAULT_IRQ815_DEF_LOCATION),"bios irq 8-15 default handler");
|
CALLBACK_Setup(call_irq815default,NULL,CB_IRET_EOI_PIC2,Real2Phys(BIOS_DEFAULT_IRQ815_DEF_LOCATION),"bios irq 8-15 default handler");
|
||||||
|
|
||||||
@ -4497,6 +4552,11 @@ private:
|
|||||||
if (!IS_PC98_ARCH)
|
if (!IS_PC98_ARCH)
|
||||||
real_writed(0,0x0e*4,CALLBACK_RealPointer(call_default2)); //design your own railroad
|
real_writed(0,0x0e*4,CALLBACK_RealPointer(call_default2)); //design your own railroad
|
||||||
|
|
||||||
|
if (IS_PC98_ARCH) {
|
||||||
|
real_writew(0,0x58A,0xFFFFU); // countdown timer value
|
||||||
|
PIC_SetIRQMask(0,true); /* PC-98 keeps the timer off unless INT 1Ch is called to set a timer interval */
|
||||||
|
}
|
||||||
|
|
||||||
real_writed(0,0x66*4,CALLBACK_RealPointer(call_default)); //war2d
|
real_writed(0,0x66*4,CALLBACK_RealPointer(call_default)); //war2d
|
||||||
real_writed(0,0x67*4,CALLBACK_RealPointer(call_default));
|
real_writed(0,0x67*4,CALLBACK_RealPointer(call_default));
|
||||||
real_writed(0,0x68*4,CALLBACK_RealPointer(call_default));
|
real_writed(0,0x68*4,CALLBACK_RealPointer(call_default));
|
||||||
@ -4981,6 +5041,8 @@ private:
|
|||||||
BIOS_Post_register_FDC();
|
BIOS_Post_register_FDC();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CPU_STI();
|
||||||
|
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
CALLBACK_HandlerObject cb_bios_scan_video_bios;
|
CALLBACK_HandlerObject cb_bios_scan_video_bios;
|
||||||
@ -5457,9 +5519,12 @@ public:
|
|||||||
|
|
||||||
/* Setup all the interrupt handlers the bios controls */
|
/* Setup all the interrupt handlers the bios controls */
|
||||||
|
|
||||||
/* INT 8 Clock IRQ Handler */
|
/* INT 8 Clock IRQ Handler */
|
||||||
call_irq0=CALLBACK_Allocate();
|
call_irq0=CALLBACK_Allocate();
|
||||||
CALLBACK_Setup(call_irq0,INT8_Handler,CB_IRQ0,Real2Phys(BIOS_DEFAULT_IRQ0_LOCATION),"IRQ 0 Clock");
|
if (IS_PC98_ARCH)
|
||||||
|
CALLBACK_Setup(call_irq0,INT8_PC98_Handler,CB_IRET,Real2Phys(BIOS_DEFAULT_IRQ0_LOCATION),"IRQ 0 Clock");
|
||||||
|
else
|
||||||
|
CALLBACK_Setup(call_irq0,INT8_Handler,CB_IRQ0,Real2Phys(BIOS_DEFAULT_IRQ0_LOCATION),"IRQ 0 Clock");
|
||||||
|
|
||||||
/* INT 11 Get equipment list */
|
/* INT 11 Get equipment list */
|
||||||
callback[1].Install(&INT11_Handler,CB_IRET,"Int 11 Equipment");
|
callback[1].Install(&INT11_Handler,CB_IRET,"Int 11 Equipment");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user