dosbox-wii/src/ints/bios.cpp
2009-05-02 21:27:47 +00:00

286 lines
8.4 KiB
C++

/*
* Copyright (C) 2002 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 <time.h>
#include "dosbox.h"
#include "bios.h"
#include "regs.h"
#include "callback.h"
#include "inout.h"
#include "mem.h"
#include "pic.h"
static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c;
static Bitu call_int1;
static Bitu INT1A_Handler(void) {
switch (reg_ah) {
case 0x00: /* Get System time */
{
Bit32u ticks=mem_readd(BIOS_TIMER);
reg_al=0; /* Midnight never passes :) */
reg_cx=(Bit16u)(ticks >> 16);
reg_dx=(Bit16u)(ticks & 0xffff);
break;
}
case 0x01: /* Set System time */
mem_writed(BIOS_TIMER,(reg_cx<<16)|reg_dx);
break;
case 0x02: /* GET REAL-TIME CLOCK TIME (AT,XT286,PS) */
reg_dx=reg_cx=0;
CALLBACK_SCF(false);
LOG_WARN("INT1A:02:Faked RTC get time call");
break;
case 0x04: /* GET REAL-TIME ClOCK DATA (AT,XT286,PS) */
reg_dx=reg_cx=0;
CALLBACK_SCF(false);
LOG_WARN("INT1A:04:Faked RTC get date call");
break;
case 0x80: /* Pcjr Setup Sound Multiplexer */
LOG_WARN("INT1A:80:Setup tandy sound multiplexer to %d",reg_al);
break;
case 0x81: /* Tandy sound system checks */
LOG_WARN("INT1A:81:Tandy DAC Check failing");
break;
/*
INT 1A - Tandy 2500, Tandy 1000L series - DIGITAL SOUND - INSTALLATION CHECK
AX = 8100h
Return: AL > 80h if supported
AX = 00C4h if supported (1000SL/TL)
CF set if sound chip is busy
CF clear if sound chip is free
Note: the value of CF is not definitive; call this function until CF is
clear on return, then call AH=84h"Tandy"
*/
default:
LOG_WARN("INT1A:Undefined call %2X",reg_ah);
}
return CBRET_NONE;
}
static Bitu INT11_Handler(void) {
/*
AX = BIOS equipment list word
bits
0 floppy disk(s) installed (see bits 6-7)
1 80x87 coprocessor installed
2,3 number of 16K banks of RAM on motherboard (PC only)
number of 64K banks of RAM on motherboard (XT only)
2 pointing device installed (PS)
3 unused (PS)
4-5 initial video mode
00 EGA, VGA, or PGA
01 40x25 color
10 80x25 color
11 80x25 monochrome
6-7 number of floppies installed less 1 (if bit 0 set)
8 DMA support installed (PCjr, some Tandy 1000s, 1400LT)
9-11 number of serial ports installed
12 game port installed
13 serial printer attached (PCjr)
internal modem installed (PC/Convertible)
14-15 number of parallel ports installed
*/
reg_eax=0x104D;
return CBRET_NONE;
}
static Bitu INT8_Handler(void) {
/* Increase the bios tick counter */
mem_writed(BIOS_TIMER,mem_readd(BIOS_TIMER)+1);
/* decrease floppy motor timer */
Bit8u val = mem_readb(BIOS_DISK_MOTOR_TIMEOUT);
if (val>0) mem_writeb(BIOS_DISK_MOTOR_TIMEOUT,val-1);
/* and running drive */
mem_writeb(BIOS_DRIVE_RUNNING,mem_readb(BIOS_DRIVE_RUNNING) & 0xF0);
// Save ds,dx,ax
Bit16u oldds = SegValue(ds);
Bit16u olddx = reg_dx;
Bit16u oldax = reg_ax;
// run int 1c
CALLBACK_RunRealInt(0x1c);
IO_Write(0x20,0x20);
// restore old values
SegSet16(ds,oldds);
reg_dx = olddx;
reg_ax = oldax;
return CBRET_NONE;
};
static Bitu INT1C_Handler(void) {
return CBRET_NONE;
};
static Bitu INT12_Handler(void) {
reg_ax=mem_readw(BIOS_MEMORY_SIZE);
return CBRET_NONE;
};
static Bitu INT17_Handler(void) {
LOG_ERROR("INT17:Not supported call for bios printer support");
switch(reg_ah) {
case 0x00: /* PRINTER: Write Character */
reg_ah=1; /* Report a timeout */
break;
case 0x01: /* PRINTER: Initialize port */
break;
case 0x02: /* PRINTER: Get Status */
reg_ah=0;
break;
default:
E_Exit("Unhandled INT 17 call %2X",reg_ah);
};
return CBRET_NONE;
};
static void WaitFlagEvent(void) {
PhysPt where=Real2Phys(mem_readd(BIOS_WAIT_FLAG_POINTER));
mem_writeb(where,mem_readb(where)|0x80);
mem_writeb(BIOS_WAIT_FLAG_ACTIVE,0);
}
static Bitu INT15_Handler(void) {
switch (reg_ah) {
case 0x06:
LOG_WARN("Calling unkown int15 function 6");
break;
case 0xC0: /* Get Configuration*/
LOG_WARN("Request BIOS Configuration INT 15 C0");
CALLBACK_SCF(true);
break;
case 0x4f: /* BIOS - Keyboard intercept */
/* Carry should be set but let's just set it just in case */
CALLBACK_SCF(true);
break;
case 0x83: /* BIOS - SET EVENT WAIT INTERVAL */
mem_writed(BIOS_WAIT_FLAG_POINTER,RealMake(SegValue(es),reg_bx));
mem_writed(BIOS_WAIT_FLAG_COUNT,reg_cx<<16|reg_dx);
mem_writeb(BIOS_WAIT_FLAG_ACTIVE,1);
PIC_RemoveEvents(&WaitFlagEvent);
PIC_AddEvent(&WaitFlagEvent,reg_cx<<16|reg_dx);
break;
case 0x84: /* BIOS - JOYSTICK SUPPORT (XT after 11/8/82,AT,XT286,PS) */
//Does anyone even use this?
LOG_WARN("INT15:84:Bios Joystick functionality not done");
reg_ax=reg_bx=reg_cx=reg_dx=0;
break;
case 0x86: /* BIOS - WAIT (AT,PS) */
{
//TODO Perhaps really wait :)
Bit32u micro=(reg_cx<<16)|reg_dx;
CALLBACK_SCF(false);
}
case 0x88: /* SYSTEM - GET EXTENDED MEMORY SIZE (286+) */
reg_ax=0;
CALLBACK_SCF(false);
break;
case 0x90: /* OS HOOK - DEVICE BUSY */
CALLBACK_SCF(false);
reg_ah=0;
break;
case 0x91: /* OS HOOK - DEVICE POST */
CALLBACK_SCF(false);
reg_ah=0;
break;
case 0xc2: /* BIOS PS2 Pointing Device Support */
/*
Damn programs should use the mouse drivers
So let's fail these calls
*/
CALLBACK_SCF(true);
break;
case 0xc4: /* BIOS POS Programma option Select */
LOG_WARN("INT15:C4:Call for POS Function %2x",reg_al);
CALLBACK_SCF(true);
break;
default:
LOG_WARN("INT15:Unknown call %2X",reg_ah);
reg_ah=0x86;
CALLBACK_SCF(false);
}
return CBRET_NONE;
}
static Bitu INT1_Single_Step(void) {
static bool warned=false;
if (!warned) {
warned=true;
LOG_WARN("INT 1:Single Step called");
}
return CBRET_NONE;
}
void BIOS_SetupKeyboard(void);
void BIOS_SetupDisks(void);
void BIOS_Init(Section* sec) {
MSG_Add("BIOS_CONFIGFILE_HELP","Nothing to setup yet!\n");
/* Clear the Bios Data Area */
for (Bit16u i=0;i<1024;i++) real_writeb(0x40,i,0);
/* Setup all the interrupt handlers the bios controls */
/* INT 8 Clock IRQ Handler */
//TODO Maybe give this a special callback that will also call int 8 instead of starting
//a new system
call_int8=CALLBACK_Allocate();
CALLBACK_Setup(call_int8,&INT8_Handler,CB_IRET);
mem_writed(BIOS_TIMER,0); //Calculate the correct time
RealSetVec(0x8,CALLBACK_RealPointer(call_int8));
/* INT10 Video Bios */
/* INT 11 Get equipment list */
call_int11=CALLBACK_Allocate();
CALLBACK_Setup(call_int11,&INT11_Handler,CB_IRET);
RealSetVec(0x11,CALLBACK_RealPointer(call_int11));
/* INT 12 Memory Size default at 640 kb */
call_int12=CALLBACK_Allocate();
CALLBACK_Setup(call_int12,&INT12_Handler,CB_IRET);
RealSetVec(0x12,CALLBACK_RealPointer(call_int12));
mem_writew(BIOS_MEMORY_SIZE,640);
/* INT 13 Bios Disk Support */
BIOS_SetupDisks();
/* INT 15 Misc Calls */
call_int15=CALLBACK_Allocate();
CALLBACK_Setup(call_int15,&INT15_Handler,CB_IRET);
RealSetVec(0x15,CALLBACK_RealPointer(call_int15));
/* INT 16 Keyboard handled in another file */
BIOS_SetupKeyboard();
/* INT 16 Printer Routines */
call_int17=CALLBACK_Allocate();
CALLBACK_Setup(call_int17,&INT17_Handler,CB_IRET);
RealSetVec(0x17,CALLBACK_RealPointer(call_int17));
/* INT 1A TIME and some other functions */
call_int1a=CALLBACK_Allocate();
CALLBACK_Setup(call_int1a,&INT1A_Handler,CB_IRET_STI);
RealSetVec(0x1A,CALLBACK_RealPointer(call_int1a));
/* INT 1C System Timer tick called from INT 8 */
call_int1c=CALLBACK_Allocate();
CALLBACK_Setup(call_int1c,&INT1C_Handler,CB_IRET);
RealSetVec(0x1C,CALLBACK_RealPointer(call_int1c));
/* Some defeault CPU error interrupt handlers */
call_int1=CALLBACK_Allocate();
CALLBACK_Setup(call_int1,&INT1_Single_Step,CB_IRET);
RealSetVec(0x1,CALLBACK_RealPointer(call_int1));
/* Test for some hardware */
if (IO_Read(0x378)!=0xff) real_writed(0x40,0x08,0x378);
}