First CVS upload.
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@80
This commit is contained in:
parent
7d1ca9bdd4
commit
42e5d0b779
158 changed files with 42940 additions and 0 deletions
6
src/ints/Makefile.am
Normal file
6
src/ints/Makefile.am
Normal 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
235
src/ints/bios.cpp
Normal 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
95
src/ints/bios_disk.cpp
Normal 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(®_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(®_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
381
src/ints/bios_keyboard.cpp
Normal 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
165
src/ints/ems.cpp
Normal 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
278
src/ints/int10.cpp
Normal 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(®_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,®_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,®_bh);
|
||||
break;
|
||||
case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER */
|
||||
INT10_GetOverscanBorderColor(®_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,®_dh,®_ch,®_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
205
src/ints/int10.h
Normal 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
394
src/ints/int10_char.cpp
Normal 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
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
135
src/ints/int10_misc.cpp
Normal 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
403
src/ints/int10_modes.cpp
Normal 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
126
src/ints/int10_pal.cpp
Normal 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));
|
||||
}
|
||||
};
|
91
src/ints/int10_put_pixel.cpp
Normal file
91
src/ints/int10_put_pixel.cpp
Normal 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
294
src/ints/mouse.cpp
Normal 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
185
src/ints/xms.cpp
Normal 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(®_ax,®_dx);
|
||||
reg_ax<<=2;reg_dx<<=2;
|
||||
reg_bl=0;
|
||||
break;
|
||||
case XMS_ALLOCATE_EXTENDED_MEMORY: /* 09 */
|
||||
EMM_Allocate(PAGES(reg_dx*1024),®_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),®_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);
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue