1
0
Fork 0

First CVS upload.

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@80
This commit is contained in:
Sjoerd van der Berg 2002-07-27 13:08:48 +00:00
parent 7d1ca9bdd4
commit 42e5d0b779
158 changed files with 42940 additions and 0 deletions

6
src/ints/Makefile.am Normal file
View file

@ -0,0 +1,6 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libints.a
libints_a_SOURCES = mouse.cpp xms.cpp ems.cpp \
int10.cpp int10.h int10_char.cpp int10_memory.cpp int10_misc.cpp int10_modes.cpp int10_pal.cpp int10_put_pixel.cpp \
bios.cpp bios_disk.cpp bios_keyboard.cpp

235
src/ints/bios.cpp Normal file
View file

@ -0,0 +1,235 @@
/*
* 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"
static Bitu call_int1a,call_int11,call_int8,call_int17,call_int12,call_int15,call_int1c;
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);
CALLBACK_RunRealInt(0x1c);
IO_Write(0x20,0x20);
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 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 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(true);
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);
}
return CBRET_NONE;
};
static void INT15_StartUp(void) {
/* TODO Start the time correctly */
};
void BIOS_SetupKeyboard(void);
void BIOS_SetupDisks(void);
void BIOS_Init(void) {
/* 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 */
INT10_StartUp();
/* 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);
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));
}

95
src/ints/bios_disk.cpp Normal file
View file

@ -0,0 +1,95 @@
/*
* 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 "dosbox.h"
#include "callback.h"
#include "bios.h"
#include "regs.h"
#include "mem.h"
static Bitu call_int13;
static BIOS_Disk * Floppys[2];
static BIOS_Disk * Harddisks[BIOS_MAX_DISK];
static Bit8u last_status;
static Bitu INT13_FullHandler(void) {
/* Check for disk numbers */
BIOS_Disk * disk=Floppys[0];
switch (reg_ah) {
case 0x00:
last_status=reg_ah=0;
break;
case 0x01: /* Get Status of last operation */
reg_ah=last_status;
break;
case 0x02: /* Read Sectors into Memory */
last_status=reg_ah=disk->Read_Sector(&reg_al,reg_dh,reg_ch,(reg_cl & 0x3f)-1,real_off(Segs[es].value,reg_bx));
CALLBACK_SCF(false);
break;
case 0x03: /* Write Sectors from Memory */
last_status=reg_ah=disk->Write_Sector(&reg_al,reg_dh,reg_ch,(reg_cl & 0x3f)-1,real_off(Segs[es].value,reg_bx));
CALLBACK_SCF(false);
break;
default:
LOG_DEBUG("INT13:Illegal call %2X",reg_ah);
reg_ah=0xff;
CALLBACK_SCF(true);
}
return CBRET_NONE;
};
static Bitu INT13_SmallHandler(void) {
switch (reg_ah) {
case 0x02: /* Read Disk Sectors */
LOG_DEBUG("INT13:02:Read Disk Sectors not supported failing");
reg_ah=0xff;
CALLBACK_SCF(true);
break;
case 0x08: /* Get Drive Parameters */
LOG_DEBUG("INT13:08:Get Drive parameters not supported failing");
reg_ah=0xff;
CALLBACK_SCF(true);
break;
case 0xff:
default:
LOG_WARN("Illegal int 13h call %2X Fail it",reg_ah);
reg_ah=0xff;
CALLBACK_SCF(true);
}
return CBRET_NONE;
}
void BIOS_SetupDisks(void) {
/* TODO Start the time correctly */
call_int13=CALLBACK_Allocate();
#ifdef C_IMAGE
Floppys[0]=new imageDisk("c:\\test.img");
for (Bit32u i=0;i<BIOS_MAX_DISK;i++) Harddisks[i]=0;
CALLBACK_Setup(call_int13,&INT13_FullHandler,CB_IRET);
#else
CALLBACK_Setup(call_int13,&INT13_SmallHandler,CB_IRET);
#endif
RealSetVec(0x13,CALLBACK_RealPointer(call_int13));
/* Init the Disk Tables */
last_status=0;
/* Setup the Bios Area */
mem_writeb(BIOS_HARDDISK_COUNT,0);
};

381
src/ints/bios_keyboard.cpp Normal file
View file

@ -0,0 +1,381 @@
/*
* 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 "dosbox.h"
#include "callback.h"
#include "mem.h"
#include "bios.h"
#include "keyboard.h"
#include "regs.h"
#include "inout.h"
static Bitu call_int16,call_irq1;
/* Nice table from BOCHS i should feel bad for ripping this */
#define none 0
#define MAX_SCAN_CODE 0x53
static struct {
Bit16u normal;
Bit16u shift;
Bit16u control;
Bit16u alt;
} scan_to_scanascii[MAX_SCAN_CODE + 1] = {
{ none, none, none, none },
{ 0x011b, 0x011b, 0x011b, 0x0100 }, /* escape */
{ 0x0231, 0x0221, none, 0x7800 }, /* 1! */
{ 0x0332, 0x0340, 0x0300, 0x7900 }, /* 2@ */
{ 0x0433, 0x0423, none, 0x7a00 }, /* 3# */
{ 0x0534, 0x0524, none, 0x7b00 }, /* 4$ */
{ 0x0635, 0x0625, none, 0x7c00 }, /* 5% */
{ 0x0736, 0x075e, 0x071e, 0x7d00 }, /* 6^ */
{ 0x0837, 0x0826, none, 0x7e00 }, /* 7& */
{ 0x0938, 0x092a, none, 0x7f00 }, /* 8* */
{ 0x0a39, 0x0a28, none, 0x8000 }, /* 9( */
{ 0x0b30, 0x0b29, none, 0x8100 }, /* 0) */
{ 0x0c2d, 0x0c5f, 0x0c1f, 0x8200 }, /* -_ */
{ 0x0d3d, 0x0d2b, none, 0x8300 }, /* =+ */
{ 0x0e08, 0x0e08, 0x0e7f, none }, /* backspace */
{ 0x0f09, 0x0f00, none, none }, /* tab */
{ 0x1071, 0x1051, 0x1011, 0x1000 }, /* Q */
{ 0x1177, 0x1157, 0x1117, 0x1100 }, /* W */
{ 0x1265, 0x1245, 0x1205, 0x1200 }, /* E */
{ 0x1372, 0x1352, 0x1312, 0x1300 }, /* R */
{ 0x1474, 0x1454, 0x1414, 0x1400 }, /* T */
{ 0x1579, 0x1559, 0x1519, 0x1500 }, /* Y */
{ 0x1675, 0x1655, 0x1615, 0x1600 }, /* U */
{ 0x1769, 0x1749, 0x1709, 0x1700 }, /* I */
{ 0x186f, 0x184f, 0x180f, 0x1800 }, /* O */
{ 0x1970, 0x1950, 0x1910, 0x1900 }, /* P */
{ 0x1a5b, 0x1a7b, 0x1a1b, none }, /* [{ */
{ 0x1b5d, 0x1b7d, 0x1b1d, none }, /* ]} */
{ 0x1c0d, 0x1c0d, 0x1c0a, none }, /* Enter */
{ none, none, none, none }, /* L Ctrl */
{ 0x1e61, 0x1e41, 0x1e01, 0x1e00 }, /* A */
{ 0x1f73, 0x1f53, 0x1f13, 0x1f00 }, /* S */
{ 0x2064, 0x2044, 0x2004, 0x2000 }, /* D */
{ 0x2166, 0x2146, 0x2106, 0x2100 }, /* F */
{ 0x2267, 0x2247, 0x2207, 0x2200 }, /* G */
{ 0x2368, 0x2348, 0x2308, 0x2300 }, /* H */
{ 0x246a, 0x244a, 0x240a, 0x2400 }, /* J */
{ 0x256b, 0x254b, 0x250b, 0x2500 }, /* K */
{ 0x266c, 0x264c, 0x260c, 0x2600 }, /* L */
{ 0x273b, 0x273a, none, none }, /* ;: */
{ 0x2827, 0x2822, none, none }, /* '" */
{ 0x2960, 0x297e, none, none }, /* `~ */
{ none, none, none, none }, /* L shift */
{ 0x2b5c, 0x2b7c, 0x2b1c, none }, /* |\ */
{ 0x2c7a, 0x2c5a, 0x2c1a, 0x2c00 }, /* Z */
{ 0x2d78, 0x2d58, 0x2d18, 0x2d00 }, /* X */
{ 0x2e63, 0x2e43, 0x2e03, 0x2e00 }, /* C */
{ 0x2f76, 0x2f56, 0x2f16, 0x2f00 }, /* V */
{ 0x3062, 0x3042, 0x3002, 0x3000 }, /* B */
{ 0x316e, 0x314e, 0x310e, 0x3100 }, /* N */
{ 0x326d, 0x324d, 0x320d, 0x3200 }, /* M */
{ 0x332c, 0x333c, none, none }, /* ,< */
{ 0x342e, 0x343e, none, none }, /* .> */
{ 0x352f, 0x353f, none, none }, /* /? */
{ none, none, none, none }, /* R Shift */
{ 0x372a, 0x372a, none, none }, /* * */
{ none, none, none, none }, /* L Alt */
{ 0x3920, 0x3920, 0x3920, 0x3920 }, /* space */
{ none, none, none, none }, /* caps lock */
{ 0x3b00, 0x5400, 0x5e00, 0x6800 }, /* F1 */
{ 0x3c00, 0x5500, 0x5f00, 0x6900 }, /* F2 */
{ 0x3d00, 0x5600, 0x6000, 0x6a00 }, /* F3 */
{ 0x3e00, 0x5700, 0x6100, 0x6b00 }, /* F4 */
{ 0x3f00, 0x5800, 0x6200, 0x6c00 }, /* F5 */
{ 0x4000, 0x5900, 0x6300, 0x6d00 }, /* F6 */
{ 0x4100, 0x5a00, 0x6400, 0x6e00 }, /* F7 */
{ 0x4200, 0x5b00, 0x6500, 0x6f00 }, /* F8 */
{ 0x4300, 0x5c00, 0x6600, 0x7000 }, /* F9 */
{ 0x4400, 0x5d00, 0x6700, 0x7100 }, /* F10 */
{ none, none, none, none }, /* Num Lock */
{ none, none, none, none }, /* Scroll Lock */
{ 0x4700, 0x4737, 0x7700, none }, /* 7 Home */
{ 0x4800, 0x4838, none, none }, /* 8 UP */
{ 0x4900, 0x4939, 0x8400, none }, /* 9 PgUp */
{ 0x4a2d, 0x4a2d, none, none }, /* - */
{ 0x4b00, 0x4b34, 0x7300, none }, /* 4 Left */
{ 0x4c00, 0x4c35, none, none }, /* 5 */
{ 0x4d00, 0x4d36, 0x7400, none }, /* 6 Right */
{ 0x4e2b, 0x4e2b, none, none }, /* + */
{ 0x4f00, 0x4f31, 0x7500, none }, /* 1 End */
{ 0x5000, 0x5032, none, none }, /* 2 Down */
{ 0x5100, 0x5133, 0x7600, none }, /* 3 PgDn */
{ 0x5200, 0x5230, none, none }, /* 0 Ins */
{ 0x5300, 0x532e, none, none } /* Del */
};
/*
Old Stuff not needed after i ripped Bochs :)
static Bit8u KeyNoShift[128]={
27,'1','2','3', '4','5','6','7', '8','9','0','-', '=',8,9,'q',
'w','e','r','t', 'y','u','i','o', 'p','[',']',13, 255,'a','s','d',
'f','g','h','j', 'k','l',';','\'', '`',255,'\\','z', 'x','c','v','b',
'n','m',',','.', '/',255,'*',255, ' ',255,0,0, 0,0,0,0,
0,0,0,0, 255,255,0,0, 0,'-',0,255, 0,'+',0,0,
0,0,0,0, 0
};
static Bit8u KeyShift[128]={
27,'!','@','#', '$','%','^','&', '*','(',')','_', '+',8,9,'Q',
'W','E','R','T', 'Y','U','I','O', 'P','{','}',13, 255,'A','S','D',
'F','G','H','J', 'K','L',':','"', '~',255,'|','Z', 'X','C','V','B',
'N','M','<','>', '?',255,'*',255, ' ',255,0,0, 0,0,0,0,
0,0,0,0, 255,255,0,0, 0,'-',0,255, 0,'+',0,0,
0,0,0,0, 0
};
*/
static void add_key(Bit16u code) {
Bit16u start,end,head,tail,ttail;
start=mem_readw(BIOS_KEYBOARD_BUFFER_START);
end =mem_readw(BIOS_KEYBOARD_BUFFER_END);
head =mem_readw(BIOS_KEYBOARD_BUFFER_HEAD);
tail =mem_readw(BIOS_KEYBOARD_BUFFER_TAIL);
ttail=tail+2;
if (ttail>=end) ttail=start;
/* Check for buffer Full */
//TODO Maybe beeeeeeep or something although that should happend when internal buffer is full
if (ttail==head) return;
real_writew(0x40,tail,code);
mem_writew(BIOS_KEYBOARD_BUFFER_TAIL,ttail);
}
static Bit16u get_key(void) {
Bit16u start,end,head,tail,thead;
start=mem_readw(BIOS_KEYBOARD_BUFFER_START);
end =mem_readw(BIOS_KEYBOARD_BUFFER_END);
head =mem_readw(BIOS_KEYBOARD_BUFFER_HEAD);
tail =mem_readw(BIOS_KEYBOARD_BUFFER_TAIL);
if (head==tail) return 0;
thead=head+2;
if (thead>=end) thead=start;
mem_writew(BIOS_KEYBOARD_BUFFER_HEAD,thead);
return real_readw(0x40,head);
}
static Bit16u check_key(void) {
Bit16u head,tail;
head =mem_readw(BIOS_KEYBOARD_BUFFER_HEAD);
tail =mem_readw(BIOS_KEYBOARD_BUFFER_TAIL);
if (head==tail) return 0;
return real_readw(0x40,head);
}
/* Flag Byte 1
bit 7 =1 INSert active
bit 6 =1 Caps Lock active
bit 5 =1 Num Lock active
bit 4 =1 Scroll Lock active
bit 3 =1 either Alt pressed
bit 2 =1 either Ctrl pressed
bit 1 =1 Left Shift pressed
bit 0 =1 Right Shift pressed
*/
/* Flag Byte 2
bit 7 =1 INSert pressed
bit 6 =1 Caps Lock pressed
bit 5 =1 Num Lock pressed
bit 4 =1 Scroll Lock pressed
bit 3 =1 Pause state active
bit 2 =1 Sys Req pressed
bit 1 =1 Left Alt pressed
bit 0 =1 Left Ctrl pressed
*/
/*
Keyboard status byte 3
bit 7 =1 read-ID in progress
bit 6 =1 last code read was first of two ID codes
bit 5 =1 force Num Lock if read-ID and enhanced keyboard
bit 4 =1 enhanced keyboard installed
bit 3 =1 Right Alt pressed
bit 2 =1 Right Ctrl pressed
bit 1 =1 last code read was E0h
bit 0 =1 last code read was E1h
*/
static Bitu IRQ1_Handler(void) {
//TODO CAPSLOCK NUMLOCK SCROLLLOCK maybe :)
Bit8u code=IO_Read(0x60);
//TODO maybe implement the int 0x15 ah=4f scancode lookup hook
/* Changed it so the flag handling takes place in here too */
Bit8u flags1=mem_readb(BIOS_KEYBOARD_FLAGS1);
Bit8u flags2=mem_readb(BIOS_KEYBOARD_FLAGS2);
Bit8u flags3=mem_readb(BIOS_KEYBOARD_FLAGS3);
switch (code) {
/* First the hard ones */
case 0xe0:
//TODO Think of something else maybe
flags3|=2;
break;
case 29: /* Ctrl Pressed */
flags1|=4;
if (flags3 & 2) flags3|=4;
else flags2|=1;
break;
case 157: /* Ctrl Released */
flags1&=~4;
if (flags3 & 2) flags3&=~4;
else flags2&=~1;
break;
case 42: /* Left Shift Pressed */
flags1|=2;
break;
case 170: /* Left Shift Released */
flags1&=~2;
break;
case 54: /* Right Shift Pressed */
flags1|=1;
break;
case 182: /* Right Shift Released */
flags1&=~1;
break;
case 56: /* Alt Pressed */
flags1|=8;
if (flags3 & 2) flags3|=8;
else flags2|=2;
break;
case 184: /* Alt Released */
flags1&=~8;
if (flags3 & 2) flags3&=~8;
else flags2&=~2;
break;
#if 0
case 58:p_capslock=true;break; /* Caps Lock */
case 186:p_capslock=false;break;
case 69:p_numlock=true;break; /* Num Lock */
case 197:p_numlock=false;break;
case 70:p_scrolllock=true;break; /* Scroll Lock */
case 198:p_scrolllock=false;break;
case 82:p_insert=true;break; /* Insert */
case 210:p_insert=false;a_insert=!a_insert;break;
#endif
default: /* Normal Key */
Bit16u asciiscan;
/* Now Handle the releasing of keys and see if they match up for a code */
flags3&=~2; //Reset 0xE0 Flag
/* Handle the actual scancode */
if (code & 0x80) goto irq1_end;
if (code > MAX_SCAN_CODE) goto irq1_end;
if (flags1 & 8) { /* Alt is being pressed */
asciiscan=scan_to_scanascii[code].alt;
} else if (flags1 & 4) { /* Ctrl is being pressed */
asciiscan=scan_to_scanascii[code].control;
} else if (flags1 & 3) { /* Either shift is being pressed */
//TODO Maybe check for Capslock sometime in some bored way
asciiscan=scan_to_scanascii[code].shift;
} else {
asciiscan=scan_to_scanascii[code].normal;
}
add_key(asciiscan);
};
irq1_end:
mem_writeb(BIOS_KEYBOARD_FLAGS1,flags1);
mem_writeb(BIOS_KEYBOARD_FLAGS2,flags2);
mem_writeb(BIOS_KEYBOARD_FLAGS3,flags3);
IO_Write(0x20,0x20);
/* Signal the keyboard for next code */
Bit8u old61=IO_Read(0x61);
IO_Write(0x61,old61 | 128);
IO_Write(0x61,old61 & 127);
return CBRET_NONE;
}
static Bitu INT16_Handler(void) {
Bit16u temp;
switch (reg_ah) {
case 0x00: /* GET KEYSTROKE */
case 0x10:
{
//TODO find a more elegant way to do this
do {
temp=get_key();
if (temp==0) { flags.intf=true;CALLBACK_Idle();};
} while (temp==0);
reg_ax=temp;
break;
}
case 0x01: /* CHECK FOR KEYSTROKE */
case 0x11:
temp=check_key();
if (temp==0) {
CALLBACK_SZF(true);
} else {
CALLBACK_SZF(false);
reg_ax=temp;
}
break;
case 0x02: /* GET SHIFT FlAGS */
reg_al=mem_readb(BIOS_KEYBOARD_FLAGS1);
break;
case 0x03: /* SET TYPEMATIC RATE AND DELAY */
//Have to implement this trhough SDL
LOG_DEBUG("INT16:Unhandled Typematic Rate Call %2X",reg_al);
break;
case 0x05: /* STORE KEYSTROKE IN KEYBOARD BUFFER */
//TODO make add_key bool :)
add_key(reg_ax);
reg_al=0;
break;
case 0x12: /* GET EXTENDED SHIFT STATES */
reg_al=mem_readb(BIOS_KEYBOARD_FLAGS1);
reg_ah=mem_readb(BIOS_KEYBOARD_FLAGS2);
break;
case 0x55:
/* Weird call used by some dos apps */
LOG_DEBUG("INT16:55:Word TSR compatible call");
break;
default:
E_Exit("INT16:Unhandled call %02X",reg_ah);
break;
};
return CBRET_NONE;
}
static void InitBiosSegment(void) {
/* Setup the variables for keyboard in the bios data segment */
mem_writew(BIOS_KEYBOARD_BUFFER_START,0x1e);
mem_writew(BIOS_KEYBOARD_BUFFER_END,0x3e);
mem_writew(BIOS_KEYBOARD_BUFFER_HEAD,0x1e);
mem_writew(BIOS_KEYBOARD_BUFFER_TAIL,0x1e);
mem_writeb(BIOS_KEYBOARD_FLAGS1,0);
mem_writeb(BIOS_KEYBOARD_FLAGS2,0);
mem_writeb(BIOS_KEYBOARD_FLAGS3,16); /* Enhanced keyboard installed */
}
void BIOS_SetupKeyboard(void) {
/* Init the variables */
InitBiosSegment();
/* Allocate a callback for int 0x16 and for standard IRQ 1 handler */
call_int16=CALLBACK_Allocate();
call_irq1=CALLBACK_Allocate();
CALLBACK_Setup(call_int16,&INT16_Handler,CB_IRET);
RealSetVec(0x16,CALLBACK_RealPointer(call_int16));
CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRET);
RealSetVec(0x9,CALLBACK_RealPointer(call_irq1));
}

165
src/ints/ems.cpp Normal file
View file

@ -0,0 +1,165 @@
/*
* 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 <string.h>
#include "dosbox.h"
#include "callback.h"
#include "mem.h"
#include "bios.h"
#include "keyboard.h"
#include "regs.h"
#include "inout.h"
#include "dos_inc.h"
#define PAGEFRAME_SEG 0xe000
class device_EMS : public DOS_Device {
public:
device_EMS();
bool Read(Bit8u * data,Bit16u * size);
bool Write(Bit8u * data,Bit16u * size);
bool Seek(Bit32u * pos,Bit32u type);
bool Close();
Bit16u GetInformation(void);
private:
Bit8u cache;
};
bool device_EMS::Read(Bit8u * data,Bit16u * size) {
return false;
}
bool device_EMS::Write(Bit8u * data,Bit16u * size) {
return false;
}
bool device_EMS::Seek(Bit32u * pos,Bit32u type) {
return false;
}
bool device_EMS::Close() {
return false;
}
Bit16u device_EMS::GetInformation(void) {
return 0x8093;
};
device_EMS::device_EMS() {
name="EMMXXXX0";
}
PageEntry ems_entries[4];
Bitu call_int67;
static Bitu INT67_Handler(void) {
switch (reg_ah) {
case 0x40: /* Get Status */
reg_ah=0; //Status ok :)
break;
case 0x41: /* Get PageFrame Segment */
reg_bx=PAGEFRAME_SEG;
reg_ah=0;
break;
case 0x42: /* Get number of pages */
{
//HEHE Hope this works not exactly like the specs but who cares
Bit16u maxfree,total;
EMM_GetFree(&maxfree,&total);
reg_dx=maxfree>>2;
reg_bx=total>>2;
reg_ah=0;
};
break;
case 0x43: /* Get Handle and Allocate Pages */
{
if (!reg_bx) { reg_ah=0x89;break; }
Bit16u handle;
EMM_Allocate(reg_bx*4,&handle);
if (handle) {
reg_ah=0;
reg_dx=handle;
} else { reg_ah=0x88; }
break;
}
case 0x44: /* Map Memory */
{
if (reg_al>3) { reg_ah=0x8b;break; }
HostPt pagestart=memory+EMM_Handles[reg_dx].phys_base+reg_bx*16*1024;
ems_entries[reg_al].relocate=pagestart;
reg_ah=0;
break;
}
case 0x45: /* Release handle and free pages */
EMM_Free(reg_dx);
reg_ah=0;
break;
case 0x46: /* Get EMM Version */
reg_ah=0;
reg_al=0x32; //Only 3.2 support for now
break;
case 0x47: /* Save Mapping Context */
LOG_ERROR("EMS:47:Save Mapping Context not supported");
reg_ah=0x8c;
break;
case 0xDE: /* VCPI Functions */
LOG_ERROR("VCPI Functions not supported");
reg_ah=0x8c;
break;
default:
LOG_ERROR("EMS:Call %2X not supported",reg_ah);
reg_ah=0x8c;
break;
}
return CBRET_NONE;
}
void EMS_Init(void) {
call_int67=CALLBACK_Allocate();
CALLBACK_Setup(call_int67,&INT67_Handler,CB_IRET);
/* Register the ems device */
DOS_Device * newdev = new device_EMS();
DOS_AddDevice(newdev);
/* Setup the page handlers for the page frame */
for (Bitu i=0;i<4;i++) {
ems_entries[i].base=(PAGEFRAME_SEG<<4)+i*16*1024;
ems_entries[i].type=MEMORY_RELOCATE;
ems_entries[i].relocate=memory+(PAGEFRAME_SEG<<4)+i*16*1024;
/* Place the page handlers in the ems page fram piece of the memory handler*/
MEMORY_SetupHandler(((PAGEFRAME_SEG<<4)+i*16*1024)>>12,4,&ems_entries[i]);
}
/* Add a little hack so it appears that there is an actual ems device installed */
char * emsname="EMMXXXX0";
Bit16u seg=DOS_GetMemory(2); //We have 32 bytes
MEM_BlockWrite(real_phys(seg,0xa),emsname,strlen(emsname)+1);
/* Copy the callback piece into the beginning */
char buf[16];
MEM_BlockRead(real_phys(CB_SEG,call_int67<<4),buf,0xa);
MEM_BlockWrite(real_phys(seg,0),buf,0xa);
RealSetVec(0x67,RealMake(seg,0));
}

278
src/ints/int10.cpp Normal file
View file

@ -0,0 +1,278 @@
/*
* 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 <string.h>
#include "dosbox.h"
#include "bios.h"
#include "mem.h"
#include "callback.h"
#include "regs.h"
#include "video.h"
#include "inout.h"
#include "int10.h"
#define TEXT_SEG 0xb800
static Bitu call_10;
static bool warned_ff=false;
static Bitu INT10_Handler(void) {
switch (reg_ah) {
case 0x00: /* Set VideoMode */
INT10_SetVideoMode(reg_al);
break;
case 0x01: /* Set TextMode Cursor Shape */
LOG_WARN("INT10:01:Set textmode cursor shape not supported");
break;
case 0x02: /* Set Cursor Pos */
//TODO Check some shit but not really usefull
INT10_SetCursorPos(reg_dh,reg_dl,reg_bh);
break;
case 0x03: /* get Cursor Pos and Cursor Shape*/
//TODO the Cursor Shape Stuff
reg_dl=CURSOR_POS_COL(reg_bh);
reg_dh=CURSOR_POS_ROW(reg_bh);
break;
case 0x04: /* read light pen pos YEAH RIGHT */
LOG_WARN("INT10:04:Ligthpen not supported");
break;
case 0x05: /* Set Active Page */
INT10_SetActivePage(reg_al);
break;
case 0x06: /* Scroll Up */
//TODO Graphics mode scroll
INT10_ScrollUpWindow(reg_ch,reg_cl,reg_dh,reg_dl,reg_al,reg_bh,0xFF);
break;
case 0x07: /* Scroll Down */
INT10_ScrollDownWindow(reg_ch,reg_cl,reg_dh,reg_dl,reg_al,reg_bh,0xFF);
break;
case 0x08: /* Read character & attribute at cursor */
//TODO Check for GRAPH and then just return
INT10_ReadCharAttr(&reg_ax,reg_bh);
break;
case 0x09: /* Write Character & Attribute at cursor CX times */
INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,true);
break;
case 0x0A: /* Write Character at cursor CX times */
INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,false);
break;
case 0x0B: /* Set Background/Border Colour & Set Palette*/
break;
E_Exit("Unsupported int 10 call %02X" ,reg_ah);
break;
case 0x0C: /* Write Graphics Pixel */
INT10_PutPixel(reg_cx,reg_dx,reg_bh,reg_al);
break;
case 0x0D: /* Read Graphics Pixel */
INT10_GetPixel(reg_cx,reg_dx,reg_bh,&reg_al);
break;
case 0x0E: /* Teletype OutPut */
//TODO FIX
INT10_TeletypeOutput(reg_al,reg_bl,false,0);
// INT10_TeletypeOutput(reg_al,reg_bl,false,reg_bh);
break;
case 0x0F: /* Get videomode */
reg_bh=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
reg_al=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
reg_ah=(Bit8u)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS);
break;
case 0x10: /* EGA/VGA Palette functions */
switch (reg_al) {
case 0x00: /* SET SINGLE PALETTE REGISTER */
INT10_SetSinglePaletteRegister(reg_bl,reg_bh);
break;
case 0x01: /* SET BORDER (OVERSCAN) COLOR*/
INT10_SetOverscanBorderColor(reg_bh);
break;
case 0x02: /* SET ALL PALETTE REGISTERS */
INT10_SetAllPaletteRegisters(real_phys(Segs[es].value,reg_dx));
break;
case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */
INT10_ToggleBlinkingBit(reg_bl);
break;
case 0x07: /* GET SINGLE PALETTE REGISTER */
INT10_GetSinglePaletteRegister(reg_bl,&reg_bh);
break;
case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER */
INT10_GetOverscanBorderColor(&reg_bh);
break;
case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER */
INT10_GetAllPaletteRegisters(real_phys(Segs[es].value,reg_dx));
break;
case 0x10: /* SET INDIVIDUAL DAC REGISTER */
INT10_SetSingleDacRegister(reg_bl,reg_dh,reg_ch,reg_cl);
break;
case 0x12: /* SET BLOCK OF DAC REGISTERS */
INT10_SetDACBlock(reg_bx,reg_cx,real_phys(Segs[es].value,reg_dx));
break;
case 0x15: /* GET INDIVIDUAL DAC REGISTER */
INT10_GetSingleDacRegister(reg_bl,&reg_dh,&reg_ch,&reg_cl);
break;
case 0x17: /* GET BLOCK OF DAC REGISTER */
INT10_GetDACBlock(reg_bx,reg_cx,real_phys(Segs[es].value,reg_dx));
break;
default:
LOG_WARN("INT10:10:Unhandled EGA/VGA Palette Function %2X",reg_al);
}
break;
case 0x11: /* Character generator functions */
switch (reg_al) {
case 0x30:/* Get Font Information */
switch (reg_bh) {
case 0x00: /* interupt 0x1f vector */
{
RealPt int_1f=RealGetVec(0x1f);
SetSegment_16(es,RealSeg(int_1f));
reg_bp=RealOff(int_1f);
reg_cx=8;
}
break;
case 0x01: /* interupt 0x43 vector */
{
RealPt int_43=RealGetVec(0x43);
SetSegment_16(es,RealSeg(int_43));
reg_bp=RealOff(int_43);
reg_cx=8;
}
break;
case 0x02: /* font 8x14 */
SetSegment_16(es,RealSeg(int10_romarea.font_14));
reg_bp=RealOff(int10_romarea.font_14);
reg_cx=14;
break;
case 0x03: /* font 8x8 first 128 */
SetSegment_16(es,RealSeg(int10_romarea.font_8_first));
reg_bp=RealOff(int10_romarea.font_8_first);
reg_cx=8;
break;
case 0x04: /* font 8x8 second 128 */
SetSegment_16(es,RealSeg(int10_romarea.font_8_second));
reg_bp=RealOff(int10_romarea.font_8_second);
reg_cx=8;
break;
case 0x06: /* font 8x16 */
SetSegment_16(es,RealSeg(int10_romarea.font_16));
reg_bp=RealOff(int10_romarea.font_16);
reg_cx=16;
break;
default:
reg_cx=16;
LOG_DEBUG("INT10:11:30 Request for font %2X",reg_bh);
}
reg_dl=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS);
break;
default:
LOG_WARN("INT10:11:Unsupported character generator call %2X",reg_al);
}
break;
case 0x12: /* alternate function select */
switch (reg_bl) {
case 0x10: /* Get EGA Information */
{
reg_bh=(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)==0x3B4);
reg_bl=3; //256 kb
reg_cx=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES) & 0x0F;
break;
}
default:
LOG_WARN("Alternate functions select %2X not handled",reg_bl);
}
break;
case 0x13: /* Write String */
INT10_WriteString(reg_dh,reg_dl,reg_al,reg_bl,real_phys(Segs[es].value,reg_bp),reg_cx,reg_bh);
break;
case 0x1A: /* Display Combination */
if (reg_al==0) {
reg_bx=real_readb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX);
reg_al=0x1A;
break;
}
if (reg_al==1) {
real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,reg_bl);
reg_al=0x1A;
break;
}
LOG_DEBUG("INT10:1A:Display Combination call %2X",reg_al);
break;
case 0x1B: /* functionality State Information */
switch (reg_bx) {
case 0x0000:
INT10_GetFuncStateInformation(Segs[es].value,reg_di);
reg_al=0x1B;
break;
default:
LOG_WARN("INT10:1B:Unhandled call BX %2X",reg_bx);
}
break;
case 0xff:
if (!warned_ff) LOG_WARN("INT10:FF:Weird NC call");
warned_ff=true;
break;
default:
LOG_WARN("Unhandled INT 10 call %2X",reg_ah);
};
return CBRET_NONE;
}
static void INT10_Seg40Init(void) {
//This should fill the ega vga structures
// init detected hardware BIOS Area
real_writew(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE,real_readw(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE)&0xFFCF);
// Just for the first int10 find its children
// the default char height
real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,16);
// Clear the screen
real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,0x60);
// Set the basic screen we have
real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9);
// Set the basic modeset options
real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,0x51);
// Set the default MSR
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x09);
INT10_SetVideoMode(3);
}
static void INT10_InitVGA(void) {
/* switch to color mode and enable CPU access 480 lines */
IO_Write(0x3c2,0xc3);
/* More than 64k */
IO_Write(0x3c4,0x04);
IO_Write(0x3c5,0x02);
};
void INT10_StartUp(void) {
INT10_InitVGA();
/* Setup the INT 10 vector */
call_10=CALLBACK_Allocate();
//TODO ERRORS ERRORS ERRORS
if (call_10==-1) E_Exit("Error can't allocate Video Int 10 CallBack\n");
CALLBACK_Setup(call_10,&INT10_Handler,CB_IRET);
RealSetVec(0x10,CALLBACK_RealPointer(call_10));
//Init the 0x40 segment and init the datastructures in the the video rom area
INT10_SetupRomMemory();
INT10_Seg40Init();
};

205
src/ints/int10.h Normal file
View file

@ -0,0 +1,205 @@
/*
* 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.
*/
#define BIOSMEM_SEG 0x40
#define BIOSMEM_INITIAL_MODE 0x10
#define BIOSMEM_CURRENT_MODE 0x49
#define BIOSMEM_NB_COLS 0x4A
#define BIOSMEM_PAGE_SIZE 0x4C
#define BIOSMEM_CURRENT_START 0x4E
#define BIOSMEM_CURSOR_POS 0x50
#define BIOSMEM_CURSOR_TYPE 0x60
#define BIOSMEM_CURRENT_PAGE 0x62
#define BIOSMEM_CRTC_ADDRESS 0x63
#define BIOSMEM_CURRENT_MSR 0x65
#define BIOSMEM_CURRENT_PAL 0x66
#define BIOSMEM_NB_ROWS 0x84
#define BIOSMEM_CHAR_HEIGHT 0x85
#define BIOSMEM_VIDEO_CTL 0x87
#define BIOSMEM_SWITCHES 0x88
#define BIOSMEM_MODESET_CTL 0x89
#define BIOSMEM_DCC_INDEX 0x8A
#define BIOSMEM_VS_POINTER 0xA8
/*
*
* VGA registers
*
*/
#define VGAREG_ACTL_ADDRESS 0x3c0
#define VGAREG_ACTL_WRITE_DATA 0x3c0
#define VGAREG_ACTL_READ_DATA 0x3c1
#define VGAREG_INPUT_STATUS 0x3c2
#define VGAREG_WRITE_MISC_OUTPUT 0x3c2
#define VGAREG_VIDEO_ENABLE 0x3c3
#define VGAREG_SEQU_ADDRESS 0x3c4
#define VGAREG_SEQU_DATA 0x3c5
#define VGAREG_PEL_MASK 0x3c6
#define VGAREG_DAC_STATE 0x3c7
#define VGAREG_DAC_READ_ADDRESS 0x3c7
#define VGAREG_DAC_WRITE_ADDRESS 0x3c8
#define VGAREG_DAC_DATA 0x3c9
#define VGAREG_READ_FEATURE_CTL 0x3ca
#define VGAREG_READ_MISC_OUTPUT 0x3cc
#define VGAREG_GRDC_ADDRESS 0x3ce
#define VGAREG_GRDC_DATA 0x3cf
#define VGAREG_MDA_CRTC_ADDRESS 0x3b4
#define VGAREG_MDA_CRTC_DATA 0x3b5
#define VGAREG_VGA_CRTC_ADDRESS 0x3d4
#define VGAREG_VGA_CRTC_DATA 0x3d5
#define VGAREG_MDA_WRITE_FEATURE_CTL 0x3ba
#define VGAREG_VGA_WRITE_FEATURE_CTL 0x3da
#define VGAREG_ACTL_RESET 0x3da
#define VGAREG_MDA_MODECTL 0x3b8
#define VGAREG_CGA_MODECTL 0x3d8
#define VGAREG_CGA_PALETTE 0x3d9
/* Video memory */
#define VGAMEM_GRAPH 0xA000
#define VGAMEM_CTEXT 0xB800
#define VGAMEM_MTEXT 0xB000
/*
*
* Tables of default values for each mode
*
*/
#define MODE_MAX 0x13
#define TEXT 0x00
#define GRAPH 0x01
#define CTEXT 0x00
#define MTEXT 0x01
#define CGA 0x02
#define PLANAR1 0x03
#define PLANAR2 0x04
#define PLANAR4 0x05
#define LINEAR8 0x06
// for SVGA
#define LINEAR15 0x07
#define LINEAR16 0x08
#define LINEAR24 0x09
#define LINEAR32 0x0
#define SCREEN_SIZE(x,y) (((x*y*2)|0x00ff)+1)
#define SCREEN_MEM_START(x,y,p) ((((x*y*2)|0x00ff)+1)*p)
#define SCREEN_IO_START(x,y,p) ((((x*y)|0x00ff)+1)*p)
extern Bit8u int10_font_08[256 * 8];
extern Bit8u int10_font_14[256 * 14];
extern Bit8u int10_font_16[256 * 16];
typedef struct
{Bit8u svgamode;
Bit16u vesamode;
Bit8u type; /* TEXT, GRAPH */
Bit8u memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */
Bit8u nbpages;
Bit8u pixbits;
Bit16u swidth, sheight;
Bit16u twidth, theight;
Bit16u cwidth, cheight;
Bit16u sstart;
Bit16u slength;
Bit8u miscreg;
Bit8u pelmask;
Bit8u crtcmodel;
Bit8u actlmodel;
Bit8u grdcmodel;
Bit8u sequmodel;
Bit8u dacmodel; /* 0 1 2 3 */
} VGAMODES;
extern VGAMODES vga_modes[MODE_MAX+1];
typedef struct {
RealPt font_8_first;
RealPt font_8_second;
RealPt font_14;
RealPt font_16;
RealPt static_state;
} VGAROMAREA;
extern VGAROMAREA int10_romarea;
#define BIOS_NCOLS Bit16u ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS);
#define BIOS_NROWS Bit16u nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
inline Bit8u CURSOR_POS_COL(Bit8u page) {
return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2);
}
inline Bit8u CURSOR_POS_ROW(Bit8u page) {
return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2+1);
}
void INT10_SetVideoMode(Bit8u mode);
void INT10_ScrollUpWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines,Bit8u attr,Bit8u page);
void INT10_ScrollDownWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines,Bit8u attr,Bit8u page);
void INT10_SetActivePage(Bit8u page);
void INT10_GetFuncStateInformation(Bit16u seg,Bit16u off);
void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page);
void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page);
void INT10_ReadCharAttr(Bit16u * result,Bit8u page);
void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr);
void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page);
/* Graphics Stuff */
void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color);
void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color);
VGAMODES * GetCurrentMode(void);
/* Palette Group */
void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val);
void INT10_SetOverscanBorderColor(Bit8u val);
void INT10_SetAllPaletteRegisters(PhysPt data);
void INT10_ToggleBlinkingBit(Bit8u state);
void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val);
void INT10_GetOverscanBorderColor(Bit8u * val);
void INT10_GetAllPaletteRegisters(PhysPt data);
void INT10_SetSingleDacRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue);
void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * blue);
void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data);
void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data);
/* Sup Groups */
void INT10_SetupRomMemory(void);

394
src/ints/int10_char.cpp Normal file
View file

@ -0,0 +1,394 @@
/*
* 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.
*/
/* Character displaying moving functions */
#include "dosbox.h"
#include "bios.h"
#include "mem.h"
#include "inout.h"
#include "int10.h"
void INT10_ScrollDownWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines,Bit8u attr,Bit8u page) {
// Bit8u mode;
Bit16u fill=( (attr << 8) | ' ');
BIOS_NCOLS;BIOS_NROWS;
if(rul>rlr) return;
if(cul>clr) return;
if(rlr>=nrows) rlr=(Bit8u)nrows-1;
if(clr>=ncols) clr=(Bit8u)ncols-1;
// Get the current page
if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
/* Get this from active video mode */
Bit16u textseg=0xb800;
PhysPt start=real_phys(textseg,ncols*nrows*2*page);
Bit32u dcol=clr-cul+1;
Bit32u drow=rlr-rul+1;
Bit32u tocopy;
PhysPt dest=start+((rlr*ncols)+cul)*2;
PhysPt src = 0;/* for gcc */
if (nlines==0) {
nlines=(Bit8u)nrows;
}
if (nlines>=drow) {
tocopy=0;
} else {
tocopy=drow-nlines;
src=start+(((rul+tocopy-1)*ncols)+cul)*2;
}
for (Bit32u y=0;y<drow;y++) {
if (tocopy) {
for(Bit32u x=0;x<dcol;x++) {
mem_writew(dest,mem_readw(src));
src+=2;
dest+=2;
}
src-=(ncols+dcol)*2;
dest-=(ncols+dcol)*2;
tocopy--;
} else {
for(Bit32u x=0;x<dcol;x++) {
mem_writew(dest,fill);
dest+=2;
}
dest-=(ncols+dcol)*2;
}
}
}
void INT10_ScrollUpWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8u nlines,Bit8u attr,Bit8u page) {
// Bit8u mode;
Bit16u fill=( (attr << 8) | ' ');
BIOS_NCOLS;BIOS_NROWS;
if(rlr>nrows) rlr=(Bit8u)nrows;
if(clr>ncols) clr=(Bit8u)ncols;
if(rul>rlr) return;
if(cul>clr) return;
VGAMODES * curmode=GetCurrentMode();
switch (curmode->memmodel) {
case CGA:
{
if (nlines==0) {
/* Clear Screen that we can */
PhysPt dest=real_phys(0xb800,0);
for (Bit32u tel=0;tel<0x4000;tel++) {
mem_writew(dest,0x0000);
dest+=2;
}
return;
}
LOG_WARN("INT10:Scroll in CGA Mode");
}
case MTEXT:
case CTEXT:
break;
default:
LOG_ERROR("INT10:Scroll on non supported graphics mode");
}
// Get the current page
if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
/* Get this from active video mode */
Bit16u textseg=0xb800;
PhysPt start=real_phys(textseg,ncols*nrows*2*page);
Bit32u dcol=clr-cul+1;
Bit32u drow=rlr-rul+1;
Bit32u tocopy;
PhysPt dest=start+((rul*ncols)+cul)*2;
PhysPt src;
if (nlines==0) {
nlines=(Bit8u)nrows;
}
if (nlines>=drow) {
tocopy=0;
} else {
tocopy=drow-nlines;
src=start+(((rul+nlines)*ncols)+cul)*2;
}
for (Bit32u y=0;y<drow;y++) {
if (tocopy) {
for (Bit32u x=0;x<dcol;x++) {
mem_writew(dest,mem_readw(src));
src+=2;
dest+=2;
}
src+=(ncols-dcol)*2;
dest+=(ncols-dcol)*2;
tocopy--;
} else {
for(Bit32u x=0;x<dcol;x++) {
mem_writew(dest,fill);
dest+=2;
}
dest+=(ncols-dcol)*2;
}
}
}
void INT10_SetActivePage(Bit8u page) {
Bit16u mem_address;
Bit16u vid_address;
Bit8u cur_col=0 ,cur_row=0 ;
VGAMODES * curmode=GetCurrentMode();
if (curmode==0) return;
if (page>7) return;
switch (curmode->memmodel) {
case MTEXT:
case CTEXT:{
BIOS_NCOLS;BIOS_NROWS;
cur_col=CURSOR_POS_COL(page);
cur_row=CURSOR_POS_ROW(page);
vid_address=SCREEN_IO_START(ncols,nrows,page);
mem_address=SCREEN_MEM_START(ncols,nrows,page);
break;
}
case CGA:{
vid_address=0;
mem_address=0;
break;
}
case PLANAR4:{
mem_address=0;
vid_address=((((curmode->sheight*curmode->swidth)>>3)|0xff)+1)*page;
break;
}
default:
vid_address=0;
mem_address=0;
break;
}
// Calculate the address knowing nbcols nbrows and page num
real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address);
// CRTC regs 0x0c and 0x0d
IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0c);
IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(vid_address&0xff00)>>8);
IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0d);
IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,vid_address&0x00ff);
// And change the BIOS page
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE,page);
// Display the cursor, now the page is active
INT10_SetCursorPos(cur_row,cur_col,page);
}
void INT10_SetCursorPos(Bit8u row,Bit8u col,Bit8u page) {
Bit16u address;
if(page>7) return;
// Bios cursor pos
real_writeb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2,col);
real_writeb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2+1,row);
// Set the hardware cursor
Bit8u current=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
if(page==current) {
// Get the dimensions
BIOS_NCOLS;BIOS_NROWS;
// Calculate the address knowing nbcols nbrows and page num
address=SCREEN_IO_START(ncols,nrows,page)+col+row*ncols;
// CRTC regs 0x0e and 0x0f
IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0e);
IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,(address&0xff00)>>8);
IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS),0x0f);
IO_Write(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)+1,address&0x00ff);
}
}
void INT10_ReadCharAttr(Bit16u * result,Bit8u page) {
if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
BIOS_NCOLS;BIOS_NROWS;
Bit8u cur_row=CURSOR_POS_ROW(page);
Bit8u cur_col=CURSOR_POS_COL(page);
Bit16u address=SCREEN_MEM_START(ncols,nrows,page)+(cur_col+cur_row*ncols)*2;
*result=real_readw(0xb800,address);
}
INLINE static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) {
VGAMODES * curmode=GetCurrentMode();
switch (curmode->type) {
case TEXT:
{
// Compute the address
Bit16u address=SCREEN_MEM_START(curmode->twidth,curmode->theight,page)+(col+row*curmode->twidth)*2;
// Write the char
real_writeb(0xb800,address,chr);
if (useattr) {
real_writeb(0xb800,address+1,attr);
}
}
break;
case GRAPH:
{
/* Split this up for certain graphics modes, since in PLANAR4 especially this is sooo slow */
/* Amount of lines */
Bit8u * fontdata;
Bit16u x,y;
switch (curmode->cheight) {
case 8:
// fontdata=&int10_font_08[chr*8];
fontdata=Real2Host(RealGetVec(0x43))+chr*8;
break;
case 14:
fontdata=&int10_font_14[chr*14];
break;
case 16:
fontdata=&int10_font_16[chr*16];
break;
default:
LOG_ERROR("INT10:Teletype Illegal Font Height");
return;
}
x=8*col;
y=curmode->cheight*row;
//TODO Check for out of bounds
for (Bit8u h=0;h<curmode->cheight;h++) {
Bit8u bitsel=128;
Bit8u bitline=*fontdata++;
Bit16u tx=x;
while (bitsel) {
if (bitline&bitsel) INT10_PutPixel(tx,y,page,attr);
else INT10_PutPixel(tx,y,page,0);
tx++;
bitsel>>=1;
}
y++;
}
}
break;
}
}
void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) {
if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
Bit8u cur_row=CURSOR_POS_ROW(page);
Bit8u cur_col=CURSOR_POS_COL(page);
while (count>0) {
WriteChar(cur_col,cur_row,page,chr,attr,showattr);
count--;
}
}
void INT10_TeletypeOutput(Bit8u chr,Bit8u attr,bool showattr, Bit8u page) {
if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
BIOS_NCOLS;BIOS_NROWS;
Bit8u cur_row=CURSOR_POS_ROW(page);
Bit8u cur_col=CURSOR_POS_COL(page);
switch (chr) {
case 7:
//TODO BEEP
break;
case 8:
if(cur_col>0) cur_col--;
break;
case '\r':
cur_col=0;
break;
case '\n':
cur_col=0;
cur_row++;
break;
case '\t':
do {
INT10_TeletypeOutput(' ',attr,showattr,page);
cur_row=CURSOR_POS_ROW(page);
cur_col=CURSOR_POS_COL(page);
} while(cur_col%8==0);
break;
default:
/* Draw the actual Character */
WriteChar(cur_col,cur_row,page,chr,attr,showattr);
cur_col++;
}
if(cur_col==ncols) {
cur_col=0;
cur_row++;
}
// Do we need to scroll ?
if(cur_row==nrows) {
INT10_ScrollUpWindow(0,0,nrows-1,ncols-1,1,0x07,page);
cur_row--;
}
// Set the cursor for the page
INT10_SetCursorPos(cur_row,cur_col,page);
}
void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page) {
if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
BIOS_NCOLS;BIOS_NROWS;
Bit8u cur_row=CURSOR_POS_ROW(page);
Bit8u cur_col=CURSOR_POS_COL(page);
// if row=0xff special case : use current cursor position
if (row==0xff) {
row=cur_row;
col=cur_col;
}
INT10_SetCursorPos(row,col,page);
while (count>0) {
Bit8u chr=mem_readb(string);
string++;
if (flag&2) {
attr=mem_readb(string);
string++;
}
INT10_TeletypeOutput(chr,attr,true,page);
count--;
}
if (flag & 1) {
INT10_SetCursorPos(cur_row,cur_col,page);
}
}

1302
src/ints/int10_memory.cpp Normal file

File diff suppressed because it is too large Load diff

135
src/ints/int10_misc.cpp Normal file
View file

@ -0,0 +1,135 @@
/*
* 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 "dosbox.h"
#include "mem.h"
#include "inout.h"
#include "int10.h"
#pragma pack(1)
struct Dynamic_Functionality {
RealPt static_table; /* 00h DWORD address of static functionality table */
Bit8u cur_mode; /* 04h BYTE video mode in effect */
Bit16u num_cols; /* 05h WORD number of columns */
Bit16u regen_size; /* 07h WORD length of regen buffer in bytes */
Bit16u regen_start; /* 09h WORD starting address of regen buffer*/
Bit16u cursor_pos[8]; /* 0Bh WORD cursor position for page 0-7 */
Bit16u cursor_type; /* 1Bh WORD cursor type */
Bit8u active_page; /* 1Dh BYTE active display page */
Bit16u crtc_address; /* 1Eh WORD CRTC port address */
Bit8u reg_3x8; /* 20h BYTE current setting of register (3?8) */
Bit8u reg_3x9; /* 21h BYTE current setting of register (3?9) */
Bit8u num_rows; /* 22h BYTE number of rows */
Bit16u bytes_per_char; /* 23h WORD bytes/character */
Bit8u dcc; /* 25h BYTE display combination code of active display */
Bit8u dcc_alternate; /* 26h BYTE DCC of alternate display */
Bit16u num_colors; /* 27h WORD number of colors supported in current mode */
Bit8u num_pages; /* 29h BYTE number of pages supported in current mode */
Bit8u num_scanlines; /* 2Ah BYTE number of scan lines active mode (0,1,2,3) = (200,350,400,480) */
Bit8u pri_char_block; /* 2Bh BYTE primary character block */
Bit8u sec_char_block; /* 2Ch BYTE secondary character block */
Bit8u misc_flags; /* 2Dh BYTE miscellaneous flags
bit 0 all modes on all displays on
1 grey summing on
2 monochrome display attached
3 default palette loading disabled
4 cursor emulation enabled
5 0 = intensity; 1 = blinking
6 PS/2 P70 plasma display (without 9-dot wide font) active
7 reserved
*/
Bit8u reserved1[3]; /* 2Eh 3 BYTEs reserved (00h) */
Bit8u vid_mem; /* 31h BYTE video memory available 00h = 64K, 01h = 128K, 02h = 192K, 03h = 256K */
Bit8u savep_state_flag; /* 32h BYTE save pointer state flags
bit 0 512 character set active
1 dynamic save area present
2 alpha font override active
3 graphics font override active
4 palette override active
5 DCC override active
6 reserved
7 reserved
*/
Bit8u reserved2[13]; /* 33h 13 BYTEs reserved (00h) */
};
#pragma pack()
void INT10_GetFuncStateInformation(Bit16u seg,Bit16u off) {
PhysPt save=Real2Phys(RealMake(seg,off));
/* set static state pointer */
mem_writed(save,int10_romarea.static_state);
/* Copy BIOS Segment areas */
Bit16u i;
/* First area in Bios Seg */
for (i=0;i<30;i++) {
mem_writeb(save+0x4+i,real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE+i));
}
/* Second area */
for (i=0;i<3;i++) {
mem_writeb(save+0x22+i,real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS+i));
}
/* Zero out rest of block */
for (i=0x25;i<0x40;i++) mem_writeb(save+i,0);
/* DCC Index */
mem_writeb(save+0x25,real_readb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX));
VGAMODES * curmode=GetCurrentMode();
if (!curmode) return;
Bit16u col_count=0;
switch (curmode->memmodel) {
case CTEXT:
col_count=2;break;
case MTEXT:
col_count=16;break;
case CGA:
col_count=4;break;
case PLANAR1:
col_count=2;break;
case PLANAR2:
col_count=4;break;
case PLANAR4:
col_count=16;break;
case LINEAR8:
col_count=256;break;
}
/* Colour count */
mem_writew(save+0x27,col_count);
/* Page count */
mem_writeb(save+0x29,curmode->nbpages);
/* scan lines */
switch (curmode->sheight) {
case 200:
mem_writeb(save+0x2a,0);break;
case 350:
mem_writeb(save+0x2a,1);break;
case 400:
mem_writeb(save+0x2a,2);break;
case 480:
mem_writeb(save+0x2a,3);break;
};
//TODO Maybe misc flags
/* Video Memory available */
mem_writeb(save+0x31,3);
}

403
src/ints/int10_modes.cpp Normal file
View file

@ -0,0 +1,403 @@
/*
* 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 "dosbox.h"
#include "mem.h"
#include "inout.h"
#include "int10.h"
//TODO Maybe also add PCJR Video Modes could be nice :)
//TODO include some credits to bochs/plex86 bios i used for info/tables
VGAMODES vga_modes[MODE_MAX+1]=
{//mode vesa class model pg bits sw sh tw th cw ch sstart slength misc pelm crtc actl gdc sequ dac
{0x00, 0xFFFF, TEXT, CTEXT, 8, 4, 360, 400, 40, 25, 9, 16, 0xB800, 0x0800, 0x67, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x01, 0xFFFF, TEXT, CTEXT, 8, 4, 360, 400, 40, 25, 9, 16, 0xB800, 0x0800, 0x67, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02},
{0x02, 0xFFFF, TEXT, CTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB800, 0x1000, 0x67, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x02},
{0x03, 0xFFFF, TEXT, CTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB800, 0x1000, 0x67, 0xFF, 0x01, 0x00, 0x00, 0x01, 0x02},
{0x04, 0xFFFF, GRAPH, CGA, 4, 2, 320, 200, 40, 25, 8, 8, 0xB800, 0x0800, 0x63, 0xFF, 0x02, 0x01, 0x01, 0x02, 0x01},
{0x05, 0xFFFF, GRAPH, CGA, 1, 2, 320, 200, 40, 25, 8, 8, 0xB800, 0x0800, 0x63, 0xFF, 0x02, 0x01, 0x01, 0x02, 0x01},
{0x06, 0xFFFF, GRAPH, CGA, 1, 1, 640, 200, 80, 25, 8, 8, 0xB800, 0x1000, 0x63, 0xFF, 0x03, 0x02, 0x02, 0x03, 0x01},
{0x07, 0xFFFF, TEXT, MTEXT, 4, 4, 720, 400, 80, 25, 9, 16, 0xB000, 0x1000, 0x66, 0xFF, 0x04, 0x03, 0x03, 0x01, 0x00},
{0x0D, 0xFFFF, GRAPH, PLANAR4, 8, 4, 320, 200, 40, 25, 8, 8, 0xA000, 0x0000, 0x63, 0xFF, 0x05, 0x04, 0x04, 0x04, 0x01},
{0x0E, 0xFFFF, GRAPH, PLANAR4, 4, 4, 640, 200, 80, 25, 8, 8, 0xA000, 0x0000, 0x63, 0xFF, 0x06, 0x04, 0x04, 0x05, 0x01},
{0x0F, 0xFFFF, GRAPH, PLANAR2, 2, 2, 640, 350, 80, 25, 8, 14, 0xA000, 0x0000, 0xa2, 0xFF, 0x07, 0x05, 0x04, 0x05, 0x00},
{0x10, 0xFFFF, GRAPH, PLANAR4, 2, 4, 640, 350, 80, 25, 8, 14, 0xA000, 0x0000, 0xa3, 0xFF, 0x07, 0x06, 0x04, 0x05, 0x02},
{0x11, 0xFFFF, GRAPH, PLANAR1, 1, 1, 640, 480, 80, 30, 8, 16, 0xA000, 0x0000, 0xe3, 0xFF, 0x08, 0x07, 0x04, 0x05, 0x02},
{0x12, 0xFFFF, GRAPH, PLANAR4, 1, 4, 640, 480, 80, 30, 8, 16, 0xA000, 0x0000, 0xe3, 0xFF, 0x08, 0x06, 0x04, 0x05, 0x02},
{0x13, 0xFFFF, GRAPH, LINEAR8, 1, 8, 320, 200, 40, 25, 8, 8, 0xA000, 0x0000, 0x63, 0xFF, 0x09, 0x08, 0x05, 0x06, 0x03}
};
/* CRTC */
#define CRTC_MAX_REG 0x18
#define CRTC_MAX_MODEL 0x09
static Bit8u crtc_access[CRTC_MAX_REG+1]=
{ /* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
static Bit8u crtc_regs[CRTC_MAX_MODEL+1][CRTC_MAX_REG+1]=
{/* Model 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 */
/* 00 */ 0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,0xff,
/* 01 */ 0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,0xff,
/* 02 */ 0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,0xff,
/* 03 */ 0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,0xff,
/* 04 */ 0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,0xff,
/* 05 */ 0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,0xff,
/* 06 */ 0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,0xff,
/* 07 */ 0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,0xff,
/* 08 */ 0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xe3,0xff,
/* 09 */ 0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,0xff
};
/* Attribute Controler 0x3c0 */
#define ACTL_MAX_REG 0x14
#define ACTL_MAX_MODEL 0x08
static Bit8u actl_access[ACTL_MAX_REG+1]=
{/* 00 01 02 03 04 05 06 07 08 09 0A 0B OC OD OE OF 10 11 12 13 14 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
static Bit8u actl_regs[ACTL_MAX_MODEL+1][ACTL_MAX_REG+1]=
{/* Model 00 01 02 03 04 05 06 07 08 09 0A 0B OC OD OE OF 10 11 12 13 14 */
/* 00 */ 0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x0c,0x00,0x0f,0x08,0x00,
/* 01 */ 0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x01,0x00,0x03,0x00,0x00,
/* 02 */ 0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x01,0x00,0x01,0x00,0x00,
/* 03 */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x0e,0x00,0x0f,0x08,0x00,
/* 04 */ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x01,0x00,0x0f,0x00,0x00,
/* 05 */ 0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,0x0b,0x00,0x05,0x00,0x00,
/* 06 */ 0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x01,0x00,0x0f,0x00,0x00,
/* 07 */ 0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x01,0x00,0x01,0x00,0x00,
/* 08 */ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x41,0x00,0x0f,0x00,0x00
};
/* Sequencer 0x3c4 */
#define SEQU_MAX_REG 0x04
#define SEQU_MAX_MODEL 0x06
static Bit8u sequ_access[SEQU_MAX_REG+1]=
{ /* 00 01 02 03 04 */
0x00,0x00,0x00,0x00,0x00
};
static Bit8u sequ_regs[SEQU_MAX_MODEL+1][SEQU_MAX_REG+1]=
{/* Model 00 01 02 03 04 */
/* 00 */ 0x03,0x08,0x03,0x00,0x02,
/* 01 */ 0x03,0x00,0x03,0x00,0x02,
/* 02 */ 0x03,0x09,0x03,0x00,0x02,
/* 03 */ 0x03,0x01,0x01,0x00,0x06,
/* 04 */ 0x03,0x09,0x0f,0x00,0x06,
/* 05 */ 0x03,0x01,0x0f,0x00,0x06,
/* 06 */ 0x03,0x01,0x0f,0x00,0x0e
};
/* Graphic ctl 0x3ce */
#define GRDC_MAX_REG 0x08
#define GRDC_MAX_MODEL 0x05
static Bit8u grdc_access[GRDC_MAX_REG+1]=
{ /* 00 01 02 03 04 05 06 07 08 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
static Bit8u grdc_regs[GRDC_MAX_MODEL+1][GRDC_MAX_REG+1]=
{/* Model 00 01 02 03 04 05 06 07 08 */
/* 00 */ 0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x0f,0xff,
/* 01 */ 0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x0f,0xff,
/* 02 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x0f,0xff,
/* 03 */ 0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x0f,0xff,
/* 04 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,0xff,
/* 05 */ 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,0xff
};
/* Default Palette */
#define DAC_MAX_MODEL 3
static Bit8u dac_regs[DAC_MAX_MODEL+1]=
{0x3f,0x3f,0x3f,0xff};
/* Mono */
static Bit8u palette0[63+1][3]=
{
0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f,
0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00,
0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a,
0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f
};
static Bit8u palette1[63+1][3]=
{
0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f
};
static Bit8u palette2[63+1][3]=
{
0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a,
0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f, 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f,
0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a, 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a,
0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f, 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f,
0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a, 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a,
0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f, 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f,
0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a, 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a,
0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f
};
static Bit8u palette3[256][3]=
{
0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a,
0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f,
0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b, 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18,
0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28, 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f,
0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f, 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10,
0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00, 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00,
0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f, 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f,
0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f, 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27,
0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f, 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f,
0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37, 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f,
0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f, 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31,
0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d, 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d,
0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a, 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f,
0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c, 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07,
0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00, 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00,
0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15, 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c,
0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c, 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11,
0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e, 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e,
0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18, 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c,
0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c, 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16,
0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14, 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14,
0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a, 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c,
0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10, 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04,
0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00, 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00,
0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c, 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10,
0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10, 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a,
0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08, 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08,
0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e, 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10,
0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10, 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c,
0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b, 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b,
0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f, 0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10,
0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00
};
static Bit8u static_functionality[0x10]=
{
/* 0 */ 0xff, // All modes supported #1
/* 1 */ 0xff, // All modes supported #2
/* 2 */ 0x0f, // All modes supported #3
/* 3 */ 0x00, 0x00, 0x00, 0x00, // reserved
/* 7 */ 0x07, // 200, 350, 400 scan lines
/* 8 */ 0xFF, // FIXME i don't know what this is
/* 9 */ 0xFF, // FIXME i don't know what this is
/* a */ 0xe3, // Change to add new functions
/* b */ 0x0c, // Change to add new functions
/* c */ 0x00, // reserved
/* d */ 0x00, // reserved
/* e */ 0x00, // Change to add new functions
/* f */ 0x00 // reserved
};
static Bit8u FindVideoMode(Bit8u mode) {
Bit8u line=0xff;
for(Bit8u i=0;i<=MODE_MAX;i++) {
if(vga_modes[i].svgamode==mode) {
line=i;
break;
}
}
return line;
}
VGAMODES * GetCurrentMode(void) {
Bit8u ret=FindVideoMode(real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)&127);
if (ret==0xff) return 0;
return &vga_modes[ret];
}
void INT10_SetVideoMode(Bit8u mode) {
bool clearmem=(mode & 128)==0;
Bit8u *palette;
Bit16u i,twidth,theight,cheight;
Bit8u modeset_ctl,video_ctl,vga_switches;
Bit16u crtc_addr;
Bit8u line;
mode&=mode & 127;
line=FindVideoMode(mode);
if (line==0xff) {
LOG_ERROR("INT10:Trying to set non supported video mode %X",mode);
return;
}
twidth=vga_modes[line].twidth;
theight=vga_modes[line].theight;
cheight=vga_modes[line].cheight;
// Read the bios vga control
video_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL);
// Read the bios vga switches
vga_switches=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES);
// Read the bios mode set control
modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
if((modeset_ctl&0x08)==0) {
// Set the PEL mask
IO_Write(VGAREG_PEL_MASK,vga_modes[line].pelmask);
// Set the whole dac always, from 0
IO_Write(VGAREG_DAC_WRITE_ADDRESS,0x00);
// From which palette
switch(vga_modes[line].dacmodel) {
case 0:
palette=(Bit8u*)&palette0;
break;
case 1:
palette=(Bit8u*)&palette1;
break;
case 2:
palette=(Bit8u*)&palette2;
break;
case 3:
palette=(Bit8u*)&palette3;
break;
default:
palette=(Bit8u*)&palette0;/*for gcc*/
E_Exit("INT10: palette error in setvidmode");
break;
}
// Set the actual palette
for (i=0;i<256;i++) {
if (i<=dac_regs[vga_modes[line].dacmodel]) {
IO_Write(VGAREG_DAC_DATA,palette[(i*3)+0]);
IO_Write(VGAREG_DAC_DATA,palette[(i*3)+1]);
IO_Write(VGAREG_DAC_DATA,palette[(i*3)+2]);
} else {
IO_Write(VGAREG_DAC_DATA,0);
IO_Write(VGAREG_DAC_DATA,0);
IO_Write(VGAREG_DAC_DATA,0);
}
}
}
/* Reset Attribute ctl into address mode just to be safe */
IO_Read(VGAREG_ACTL_RESET);
// Set Attribute Ctl
for(i=0;i<=ACTL_MAX_REG;i++) {
IO_Write(VGAREG_ACTL_ADDRESS,(Bit8u)i);
IO_Write(VGAREG_ACTL_WRITE_DATA,actl_regs[vga_modes[line].actlmodel][i]);
}
// Set Sequencer Ctl
for(i=0;i<=SEQU_MAX_REG;i++) {
IO_Write(VGAREG_SEQU_ADDRESS,(Bit8u)i);
IO_Write(VGAREG_SEQU_DATA,sequ_regs[vga_modes[line].sequmodel][i]);
}
// Set Grafx Ctl
for(i=0;i<=GRDC_MAX_REG;i++) {
IO_Write(VGAREG_GRDC_ADDRESS,(Bit8u)i);
IO_Write(VGAREG_GRDC_DATA,grdc_regs[vga_modes[line].grdcmodel][i]);
}
// Set CRTC address VGA or MDA
crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS;
// Set CRTC regs
for(i=0;i<=CRTC_MAX_REG;i++) {
IO_Write(crtc_addr,(Bit8u)i);
IO_Write(crtc_addr+1,crtc_regs[vga_modes[line].crtcmodel][i]);
}
// Set the misc register
IO_Write(VGAREG_WRITE_MISC_OUTPUT,vga_modes[line].miscreg);
// Enable video
IO_Write(VGAREG_ACTL_ADDRESS,0x20);
IO_Read(VGAREG_ACTL_RESET);
Bit32u tel;
if(clearmem) {
if(vga_modes[line].type==TEXT) {
PhysPt dest=real_phys(vga_modes[line].sstart,0);
for (tel=0;tel<0x4000;tel++) {
mem_writew(dest,0x0720);
dest+=2;
}
} else {
PhysPt dest=real_phys(0xb800,0);
for (tel=0;tel<0x4000;tel++) {
mem_writew(dest,0x0000);
dest+=2;
}
dest=real_phys(0xa000,0);
for (tel=0;tel<0x8000;tel++) {
mem_writew(dest,0x0000);
dest+=2;
}
// FIXME should handle gfx mode
}
}
// Set the BIOS mem
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode|((!clearmem) << 7));
real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth);
real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,vga_modes[line].slength);
real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr);
real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theight-1);
real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight);
real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem << 7)));
real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9);
real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f);
// FIXME We nearly have the good tables. to be reworked
real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now
real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER,0x00);
real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2,0x00);
// FIXME
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but...
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but...
// Set cursor shape
if(vga_modes[line].type==TEXT) {
//TODO cursor shape biosfn_set_cursor_shape(0x06,0x07);
}
// Set cursor pos for page 0..7
for(i=0;i<8;i++) INT10_SetCursorPos(0,0,(Bit8u)i);
// Set active page 0
INT10_SetActivePage(0);
/* Set some interrupt vectors */
//TODO set 0x43 to the correct font height font
RealSetVec(0x43,int10_romarea.font_8_first);
RealSetVec(0x1F,int10_romarea.font_8_second);
};

126
src/ints/int10_pal.cpp Normal file
View file

@ -0,0 +1,126 @@
/*
* 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 "dosbox.h"
#include "mem.h"
#include "inout.h"
#include "int10.h"
#define ACTL_MAX_REG 0x14
void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) {
if(reg<=ACTL_MAX_REG) {
IO_Read(VGAREG_ACTL_RESET);
IO_Write(VGAREG_ACTL_ADDRESS,reg);
IO_Write(VGAREG_ACTL_WRITE_DATA,val);
}
}
void INT10_SetOverscanBorderColor(Bit8u val) {
IO_Read(VGAREG_ACTL_RESET);
IO_Write(VGAREG_ACTL_ADDRESS,0x11);
IO_Write(VGAREG_ACTL_WRITE_DATA,val);
}
void INT10_SetAllPaletteRegisters(PhysPt data) {
IO_Read(VGAREG_ACTL_RESET);
// First the colors
for(Bit8u i=0;i<0x10;i++) {
IO_Write(VGAREG_ACTL_ADDRESS,i);
IO_Write(VGAREG_ACTL_WRITE_DATA,mem_readb(data));
data++;
}
// Then the border
IO_Write(VGAREG_ACTL_ADDRESS,0x11);
IO_Write(VGAREG_ACTL_WRITE_DATA,mem_readb(data));
}
void INT10_ToggleBlinkingBit(Bit8u state) {
Bit8u value;
state&=0x01;
IO_Read(VGAREG_ACTL_RESET);
IO_Write(VGAREG_ACTL_ADDRESS,0x10);
value=IO_Read(VGAREG_ACTL_READ_DATA);
value&=0xf7;
value|=state<<3;
IO_Read(VGAREG_ACTL_RESET);
IO_Write(VGAREG_ACTL_ADDRESS,0x10);
IO_Write(VGAREG_ACTL_WRITE_DATA,value);
}
void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val) {
if(reg<=ACTL_MAX_REG) {
IO_Read(VGAREG_ACTL_RESET);
IO_Write(VGAREG_ACTL_ADDRESS,reg);
*val=IO_Read(VGAREG_ACTL_READ_DATA);
}
}
void INT10_GetOverscanBorderColor(Bit8u * val) {
IO_Read(VGAREG_ACTL_RESET);
IO_Write(VGAREG_ACTL_ADDRESS,0x11);
*val=IO_Read(VGAREG_ACTL_READ_DATA);
}
void INT10_GetAllPaletteRegisters(PhysPt data) {
IO_Read(VGAREG_ACTL_RESET);
// First the colors
for(Bit8u i=0;i<0x10;i++) {
IO_Write(VGAREG_ACTL_ADDRESS,i);
mem_writeb(data,IO_Read(VGAREG_ACTL_READ_DATA));
data++;
}
// Then the border
IO_Write(VGAREG_ACTL_ADDRESS,0x11);
mem_writeb(data,IO_Read(VGAREG_ACTL_READ_DATA));
}
void INT10_SetSingleDacRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue) {
IO_Write(VGAREG_DAC_WRITE_ADDRESS,(Bit8u)index);
IO_Write(VGAREG_DAC_DATA,red);
IO_Write(VGAREG_DAC_DATA,green);
IO_Write(VGAREG_DAC_DATA,blue);
}
void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * blue) {
IO_Write(VGAREG_DAC_READ_ADDRESS,index);
*red=IO_Read(VGAREG_DAC_DATA);
*green=IO_Read(VGAREG_DAC_DATA);
*blue=IO_Read(VGAREG_DAC_DATA);
}
void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data) {
IO_Write(VGAREG_DAC_WRITE_ADDRESS,(Bit8u)index);
for (;count>0;count--) {
IO_Write(VGAREG_DAC_DATA,mem_readb(data++));
IO_Write(VGAREG_DAC_DATA,mem_readb(data++));
IO_Write(VGAREG_DAC_DATA,mem_readb(data++));
}
}
void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data) {
IO_Write(VGAREG_DAC_WRITE_ADDRESS,(Bit8u)index);
for (;count>0;count--) {
mem_writeb(data++,IO_Read(VGAREG_DAC_DATA));
mem_writeb(data++,IO_Read(VGAREG_DAC_DATA));
mem_writeb(data++,IO_Read(VGAREG_DAC_DATA));
}
};

View file

@ -0,0 +1,91 @@
/*
* 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 "dosbox.h"
#include "mem.h"
#include "inout.h"
#include "int10.h"
union VGA_Memory {
Bit8u linear[64*1024*4];
Bit8u paged[64*1024][4];
};
extern VGA_Memory vga_mem;
static Bit8u cga_masks[4]={~192,~48,~12,~3};
void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) {
VGAMODES * curmode=GetCurrentMode();
switch (curmode->memmodel) {
case CGA:
{
Bit16u off=(y>>1)*80+(x>>2);
if (y&1) off+=8*1024;
Bit8u old=real_readb(0xb800,off);
old=old&cga_masks[x&3]|((color&3) << (2*(3-(x&3))));
real_writeb(0xb800,off,old);
}
break;
case PLANAR4:
{
/* Set the correct bitmask for the pixel position */
IO_Write(0x3ce,0x8);Bit8u mask=128>>(x&7);IO_Write(0x3cf,mask);
/* Set the color to set/reset register */
IO_Write(0x3ce,0x0);IO_Write(0x3cf,color);
/* Enable all the set/resets */
IO_Write(0x3ce,0x1);IO_Write(0x3cf,0xf);
//Perhaps also set mode 1
/* Calculate where the pixel is in video memory */
Bit16u base_address=((((curmode->sheight*curmode->swidth)>>3)|0xff)+1)*page;
PhysPt off=0xa0000+base_address+((y*curmode->swidth+x)>>3);
/* Bitmask and set/reset should do the rest */
mem_readb(off);
mem_writeb(off,0xff);
break;
}
case CTEXT:
case MTEXT:
case PLANAR1:
case PLANAR2:
case LINEAR8:
default:
LOG_WARN("INT10:PutPixel Unhanled memory model");
break;
}
}
void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color) {
VGAMODES * curmode=GetCurrentMode();
switch (curmode->memmodel) {
case CGA:
{
Bit16u off=(y>>1)*80+(x>>2);
if (y&1) off+=8*1024;
Bit8u val=real_readb(0xb800,off);
*color=val<<((x&3)*2);
}
break;
default:
LOG_WARN("INT10:GetPixel Unhanled memory model");
break;
}
}

294
src/ints/mouse.cpp Normal file
View file

@ -0,0 +1,294 @@
/*
* 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 <string.h>
#include "dosbox.h"
#include "callback.h"
#include "mem.h"
#include "regs.h"
#include "mouse.h"
#include "pic.h"
#include "inout.h"
static Bitu call_int33,call_int74;
struct button_event {
Bit16u type;
Bit16u buttons;
};
#define QUEUE_SIZE 32
//TODO Maybe use :)
#define MOUSE_IRQ 12
#define POS_X (Bit16s)(mouse.x*mouse.range_x)
#define POS_Y (Bit16s)(mouse.y*mouse.range_y)
static struct {
Bit16u buttons;
Bit16u times_pressed[3];
Bit16u times_released[3];
Bit16u last_released_x[3];
Bit16u last_released_y[3];
Bit16u last_pressed_x[3];
Bit16u last_pressed_y[3];
Bit16s shown;
float add_x,add_y;
Bit16u min_x,max_x,min_y,max_y;
float range_x,range_y;
float mickey_x,mickey_y;
float x,y;
button_event event_queue[QUEUE_SIZE];
Bit32u events;
Bit16u sub_seg,sub_ofs;
Bit16u sub_mask;
} mouse;
#define X_MICKEY 500
#define Y_MICKEY 500
#define MOUSE_MOVED 1
#define MOUSE_LEFT_PRESSED 2
#define MOUSE_LEFT_RELEASED 4
#define MOUSE_RIGHT_PRESSED 8
#define MOUSE_RIGHT_RELEASED 16
#define MOUSE_MIDDLE_PRESSED 32
#define MOUSE_MIDDLE_RELEASED 64
inline void Mouse_AddEvent(Bit16u type) {
if (mouse.events<QUEUE_SIZE) {
mouse.event_queue[mouse.events].type=type;
mouse.event_queue[mouse.events].buttons=mouse.buttons;
mouse.events++;
}
PIC_ActivateIRQ(12);
}
void Mouse_CursorMoved(float x,float y) {
mouse.mickey_x+=x;
mouse.mickey_y+=y;
mouse.x+=x;
if (mouse.x>1) mouse.x=1;
if (mouse.x<0) mouse.x=0;
mouse.y+=y;
if (mouse.y>1) mouse.y=1;
if (mouse.y<0) mouse.y=0;
Mouse_AddEvent(MOUSE_MOVED);
}
void Mouse_CursorSet(float x,float y) {
mouse.x=x;
mouse.y=y;
}
void Mouse_ButtonPressed(Bit8u button) {
switch (button) {
case 0:
mouse.buttons|=1;
Mouse_AddEvent(MOUSE_LEFT_PRESSED);
break;
case 1:
mouse.buttons|=2;
Mouse_AddEvent(MOUSE_RIGHT_PRESSED);
break;
case 2:
mouse.buttons|=4;
Mouse_AddEvent(MOUSE_MIDDLE_PRESSED);
break;
}
mouse.times_pressed[button]++;
mouse.last_pressed_x[button]=POS_X;
mouse.last_pressed_y[button]=POS_Y;
}
void Mouse_ButtonReleased(Bit8u button) {
switch (button) {
case 0:
mouse.buttons&=~1;
Mouse_AddEvent(MOUSE_LEFT_RELEASED);
break;
case 1:
mouse.buttons&=~2;
Mouse_AddEvent(MOUSE_RIGHT_RELEASED);
break;
case 2:
mouse.buttons&=~4;
Mouse_AddEvent(MOUSE_MIDDLE_RELEASED);
break;
}
mouse.times_released[button]++;
mouse.last_released_x[button]=POS_X;
mouse.last_released_y[button]=POS_Y;
}
static void mouse_reset(void) {
real_writed(0,(0x33<<2),CALLBACK_RealPointer(call_int33));
real_writed(0,(0x74<<2),CALLBACK_RealPointer(call_int74));
mouse.shown=-1;
mouse.min_x=0;
mouse.max_x=639;
mouse.min_y=0;
mouse.max_y=199;
mouse.range_x=639;
mouse.range_y=199;
mouse.x=320;
mouse.y=100;
mouse.events=0;
mouse.mickey_x=0;
mouse.mickey_y=0;
mouse.sub_mask=0;
mouse.sub_seg=0;
mouse.sub_ofs=0;
};
static Bitu INT33_Handler(void) {
switch (reg_ax) {
case 0x00: /* Reset Driver and Read Status */
reg_ax=0xffff;
reg_bx=0;
mouse_reset();
break;
case 0x01: /* Show Mouse */
mouse.shown++;
if (mouse.shown>0) mouse.shown=0;
break;
case 0x02: /* Hide Mouse */
mouse.shown--;
break;
case 0x03: /* Return position and Button Status */
reg_bx=mouse.buttons;
reg_cx=POS_X;
reg_dx=POS_Y;
break;
case 0x04: /* Position Mouse */
mouse.x=((float)reg_cx)/mouse.range_x;
mouse.y=((float)reg_dx)/mouse.range_y;
break;
case 0x05: /* Return Button Press Data */
{
Bit16u but=reg_bx;
reg_ax=mouse.buttons;
reg_cx=mouse.last_pressed_x[but];
mouse.last_pressed_x[but]=0;
reg_dx=mouse.last_pressed_y[but];
mouse.last_pressed_y[but]=0;
reg_bx=mouse.times_pressed[but];
mouse.times_pressed[but]=0;
break;
}
case 0x07: /* Define horizontal cursor range */
mouse.min_x=reg_cx;
mouse.max_x=reg_dx;
mouse.range_x=mouse.max_x-mouse.min_x;
//TODO Check for range start 0
break;
case 0x08: /* Define vertical cursor range */
mouse.min_y=reg_cx;
mouse.max_y=reg_dx;
mouse.range_y=mouse.max_y-mouse.min_y;
break;
case 0x09: /* Define GFX Cursor */
LOG_WARN("MOUSE:Define gfx cursor not supported");
break;
case 0x0a: /* Define Text Cursor */
/* Don't see much need for supporting this */
break;
case 0x0c: /* Define interrupt subroutine parameters */
mouse.sub_mask=reg_cx;
mouse.sub_seg=Segs[es].value;
mouse.sub_ofs=reg_dx;
break;
case 0x0f: /* Define mickey/pixel rate */
//TODO Maybe dunno for sure might be possible */
break;
case 0x0B: /* Read Motion Data */
reg_cx=(Bit16s)(mouse.mickey_x*X_MICKEY);
reg_dx=(Bit16s)(mouse.mickey_y*Y_MICKEY);
mouse.mickey_x=0;
mouse.mickey_y=0;
break;
case 0x1c: /* Set interrupt rate */
/* Can't really set a rate this is host determined */
break;
case 0x21: /* Software Reset */
//TODO reset internal mouse software variables likes mickeys
reg_ax=0xffff;
reg_bx=2;
break;
case 0x24: /* Get Software version and mouse type */
reg_bx=0x805; //Version 8.05 woohoo
reg_ch=0xff; /* Unkown type */
reg_cl=0; /* Hmm ps2 irq dunno */
break;
default:
LOG_ERROR("Mouse Function %2X",reg_ax);
};
return CBRET_NONE;
};
static Bitu INT74_Handler(void) {
if (mouse.events>0) {
mouse.events--;
/* Check for an active Interrupt Handler that will get called */
if (mouse.sub_mask & mouse.event_queue[mouse.events].type) {
/* Save lot's of registers */
Bit16u oldax,oldbx,oldcx,olddx,oldsi,olddi;
oldax=reg_ax;oldbx=reg_bx;oldcx=reg_cx;olddx=reg_dx;oldsi=reg_si;olddi=reg_di;
reg_ax=mouse.event_queue[mouse.events].type;
reg_bx=mouse.event_queue[mouse.events].buttons;
reg_cx=POS_X;
reg_dx=POS_Y;
reg_si=(Bit16s)(mouse.mickey_x*X_MICKEY);
reg_di=(Bit16s)(mouse.mickey_y*Y_MICKEY);
if (mouse.event_queue[mouse.events].type==MOUSE_MOVED) {
mouse.mickey_x=0;
mouse.mickey_y=0;
}
CALLBACK_RunRealFar(mouse.sub_seg,mouse.sub_ofs);
reg_ax=oldax;reg_bx=oldbx;reg_cx=oldcx;reg_dx=olddx;reg_si=oldsi;reg_di=olddi;
}
}
IO_Write(0xa0,0x20);
/* Check for more Events if so reactivate IRQ */
if (mouse.events) {
PIC_ActivateIRQ(12);
}
return CBRET_NONE;
};
void MOUSE_Init(void) {
call_int33=CALLBACK_Allocate();
CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET);
real_writed(0,(0x33<<2),CALLBACK_RealPointer(call_int33));
call_int74=CALLBACK_Allocate();
CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRET);
real_writed(0,(0x74<<2),CALLBACK_RealPointer(call_int74));
memset((void *)&mouse,0,sizeof(mouse));
mouse_reset();
};

185
src/ints/xms.cpp Normal file
View file

@ -0,0 +1,185 @@
/*
* 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 <string.h>
#include "dosbox.h"
#include "callback.h"
#include "mem.h"
#include "regs.h"
#include "dos_system.h"
#define XMS_VERSION 0x0300 /* version 3.00 */
#define XMS_DRIVER_VERSION 0x0301 /* my driver version 3.01 */
#define XMS_GET_VERSION 0x00
#define XMS_ALLOCATE_HIGH_MEMORY 0x01
#define XMS_FREE_HIGH_MEMORY 0x02
#define XMS_GLOBAL_ENABLE_A20 0x03
#define XMS_GLOBAL_DISABLE_A20 0x04
#define XMS_LOCAL_ENABLE_A20 0x05
#define XMS_LOCAL_DISABLE_A20 0x06
#define XMS_QUERY_A20 0x07
#define XMS_QUERY_FREE_EXTENDED_MEMORY 0x08
#define XMS_ALLOCATE_EXTENDED_MEMORY 0x09
#define XMS_FREE_EXTENDED_MEMORY 0x0a
#define XMS_MOVE_EXTENDED_MEMORY_BLOCK 0x0b
#define XMS_LOCK_EXTENDED_MEMORY_BLOCK 0x0c
#define XMS_UNLOCK_EXTENDED_MEMORY_BLOCK 0x0d
#define XMS_GET_EMB_HANDLE_INFORMATION 0x0e
#define XMS_RESIZE_EXTENDED_MEMORY_BLOCK 0x0f
#define XMS_ALLOCATE_UMB 0x10
#define XMS_DEALLOCATE_UMB 0x11
#define HIGH_MEMORY_IN_USE 0x92
#define HIGH_MEMORY_NOT_ALLOCATED 0x93
#define XMS_OUT_OF_SPACE 0xa0
#define XMS_INVALID_HANDLE 0xa2
static Bit16u call_xms;
static RealPt xms_callback;
static bool multiplex_xms(void) {
switch (reg_ax) {
case 0x4300: /* XMS installed check */
reg_al=0x80;
return true;
case 0x4310: /* XMS handler seg:offset */
SetSegment_16(es,RealSeg(xms_callback));
reg_bx=RealOff(xms_callback);
return true;
}
return false;
};
#if defined (_MSC_VER)
#pragma pack(1)
#endif
struct XMS_MemMove{
Bit32u length;
Bit16u src_handle;
RealPt src_offset;
Bit16u dest_handle;
RealPt dest_offset;
}
#if defined (_MSC_VER)
;
#pragma pack()
#else
__attribute__ ((packed));
#endif
static void XMS_MoveBlock(PhysPt block,Bit8u * result) {
XMS_MemMove moveblock;
//TODO Will not work on other endian, probably base it on a class would be nice
MEM_BlockRead(block,(Bit8u *)&moveblock,sizeof(XMS_MemMove));
HostPt src;
PhysPt dest;
if (moveblock.src_handle) {
src=memory+EMM_Handles[moveblock.src_handle].phys_base+moveblock.src_offset;
} else {
src=Real2Host(moveblock.src_offset);
}
if (moveblock.dest_handle) {
dest=EMM_Handles[moveblock.dest_handle].phys_base+moveblock.dest_offset;
} else {
dest=Real2Phys(moveblock.dest_offset);
}
//memcpy((void *)dest,(void *)src,moveblock.length);
MEM_BlockWrite(dest,src,moveblock.length);
*result=0;
};
Bitu XMS_Handler(void) {
switch (reg_ah) {
case XMS_GET_VERSION: /* 00 */
reg_ax=XMS_VERSION;
reg_bx=XMS_DRIVER_VERSION;
reg_dx=0; //TODO HMA Maybe
break;
case XMS_ALLOCATE_HIGH_MEMORY: /* 01 */
case XMS_FREE_HIGH_MEMORY: /* 02 */
case XMS_GLOBAL_ENABLE_A20: /* 03 */
case XMS_GLOBAL_DISABLE_A20: /* 04 */
case XMS_LOCAL_ENABLE_A20: /* 05 */
case XMS_LOCAL_DISABLE_A20: /* 06 */
case XMS_QUERY_A20: /* 07 */
LOG_WARN("XMS:Unhandled call %2X",reg_ah);break;
case XMS_QUERY_FREE_EXTENDED_MEMORY: /* 08 */
EMM_GetFree(&reg_ax,&reg_dx);
reg_ax<<=2;reg_dx<<=2;
reg_bl=0;
break;
case XMS_ALLOCATE_EXTENDED_MEMORY: /* 09 */
EMM_Allocate(PAGES(reg_dx*1024),&reg_dx);
if (reg_dx) reg_ax=1;
else { reg_ax=0;reg_bl=0xb0; }
break;
case XMS_FREE_EXTENDED_MEMORY: /* 0a */
EMM_Free(reg_dx);
reg_ax=1;
break;
case XMS_MOVE_EXTENDED_MEMORY_BLOCK: /* 0b */
XMS_MoveBlock(real_phys(Segs[ds].value,reg_si),&reg_bl);
if (reg_bl) reg_ax=0;
else reg_ax=1;
break;
case XMS_LOCK_EXTENDED_MEMORY_BLOCK: /* 0c */
if ((!EMM_Handles[reg_dx].active) || (EMM_Handles[reg_dx].free)) {
reg_ax=0;
reg_bl=0xa2; /* Invalid block */
break;
}
reg_ax=1;
reg_bx=(Bit16u)((EMM_Handles[reg_dx].phys_base) & 0xffff);
reg_dx=(Bit16u)((EMM_Handles[reg_dx].phys_base >> 16) & 0xffff);
break;
case XMS_UNLOCK_EXTENDED_MEMORY_BLOCK: /* 0d */
reg_ax=1;
break;
case XMS_GET_EMB_HANDLE_INFORMATION: /* 0e */
LOG_WARN("XMS:Unhandled call %2X",reg_ah);break;
case XMS_RESIZE_EXTENDED_MEMORY_BLOCK: /* 0f */
LOG_WARN("XMS:Unhandled call %2X",reg_ah);break;
case XMS_ALLOCATE_UMB: /* 10 */
reg_ax=0;
reg_bl=0xb1; //No UMB Available
reg_dx=0;
break;
case XMS_DEALLOCATE_UMB: /* 11 */
default:
LOG_WARN("XMS:Unhandled call %2X",reg_ah);break;
}
return CBRET_NONE;
}
void XMS_Init(void) {
DOS_AddMultiplexHandler(multiplex_xms);
call_xms=CALLBACK_Allocate();
CALLBACK_Setup(call_xms,&XMS_Handler,CB_RETF);
xms_callback=CALLBACK_RealPointer(call_xms);
}