mirror of
https://github.com/retro100/dosbox-wii.git
synced 2025-02-28 15:53:42 +01:00
sync with upstream svn
This commit is contained in:
parent
806dc853cc
commit
ccd9bdbeac
59
README
59
README
@ -139,7 +139,7 @@ Type INTRO in DOSBox for a quick tour.
|
|||||||
It is essential that you get familiar with the idea of mounting, DOSBox does not
|
It is essential that you get familiar with the idea of mounting, DOSBox does not
|
||||||
automatically make any drive (or a part of it) accessible to the emulation. See
|
automatically make any drive (or a part of it) accessible to the emulation. See
|
||||||
the FAQ entry "How to start?" as well as the description of the MOUNT command
|
the FAQ entry "How to start?" as well as the description of the MOUNT command
|
||||||
(section 4: "Internal Programs"). If you have your game on a cdrom you may try
|
(Section 4: "Internal Programs"). If you have your game on a cdrom you may try
|
||||||
this guide: http://vogons.zetafleet.com/viewtopic.php?t=8933
|
this guide: http://vogons.zetafleet.com/viewtopic.php?t=8933
|
||||||
|
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ START: How to start?
|
|||||||
AUTOMATION: Do I always have to type these commands?
|
AUTOMATION: Do I always have to type these commands?
|
||||||
In the DOSBox configuration file is an [autoexec] section. The commands
|
In the DOSBox configuration file is an [autoexec] section. The commands
|
||||||
present there are run when DOSBox starts, so you can use this section
|
present there are run when DOSBox starts, so you can use this section
|
||||||
for the mounting. Look at Section 13: The configuration (options) file
|
for the mounting. Look at Section 13: "The configuration (options) file".
|
||||||
|
|
||||||
|
|
||||||
FULLSCREEN: How do I change to fullscreen?
|
FULLSCREEN: How do I change to fullscreen?
|
||||||
@ -313,11 +313,12 @@ SOUND: What sound hardware does DOSBox presently emulate?
|
|||||||
SOUND: The sound stutters or sounds stretched/weird.
|
SOUND: The sound stutters or sounds stretched/weird.
|
||||||
You may be using too much CPU power to keep DOSBox running at the current
|
You may be using too much CPU power to keep DOSBox running at the current
|
||||||
speed. You can lower the cycles, skip frames, reduce the sampling rate of
|
speed. You can lower the cycles, skip frames, reduce the sampling rate of
|
||||||
the respective sound device, increase the prebuffer. See section 13: "The
|
the respective sound device, increase the prebuffer. See Section 13: "The
|
||||||
configuration (options) file"
|
configuration (options) file".
|
||||||
If you are using cycles=max or =auto, then make sure that there is no
|
If you are using 'cycles=max' or 'cycles=auto', then make sure that there is
|
||||||
background processes interfering! (especially if they access the harddisk)
|
no background processes interfering! (especially if they access the harddisk)
|
||||||
Also look at Section 10. "How to speed up/slow down DOSBox"
|
Also look at Section 10: "How to speed up/slow down DOSBox" as well as
|
||||||
|
Section 11: "Troubleshooting".
|
||||||
|
|
||||||
|
|
||||||
KEYBOARD: I can't type \ or : in DOSBox.
|
KEYBOARD: I can't type \ or : in DOSBox.
|
||||||
@ -326,7 +327,7 @@ KEYBOARD: I can't type \ or : in DOSBox.
|
|||||||
detected), or the key mapping is wrong.
|
detected), or the key mapping is wrong.
|
||||||
Some possible fixes:
|
Some possible fixes:
|
||||||
1. Use / instead, or ALT-58 for : and ALT-92 for \.
|
1. Use / instead, or ALT-58 for : and ALT-92 for \.
|
||||||
2. Change the DOS keyboard layout (see Section 8: Keyboard Layout).
|
2. Change the DOS keyboard layout (see Section 8: "Keyboard Layout").
|
||||||
3. Add the commands you want to execute to the [autoexec] section
|
3. Add the commands you want to execute to the [autoexec] section
|
||||||
of the DOSBox configuration file.
|
of the DOSBox configuration file.
|
||||||
4. Open the DOSBox configuration file and change the usescancodes entry.
|
4. Open the DOSBox configuration file and change the usescancodes entry.
|
||||||
@ -367,16 +368,16 @@ CONTROL: The character/cursor/mouse pointer always moves into one direction!
|
|||||||
|
|
||||||
|
|
||||||
SPEED: The game/application runs much too slow/too fast!
|
SPEED: The game/application runs much too slow/too fast!
|
||||||
Look at the section 10: "How to speed up/slow down DOSBox" for more
|
Look at Section 10: "How to speed up/slow down DOSBox" for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
|
|
||||||
CRASH: The game/application does not run at all/crashes!
|
CRASH: The game/application does not run at all/crashes!
|
||||||
Look at Section 11: Troubleshooting
|
Look at Section 11: "Troubleshooting".
|
||||||
|
|
||||||
|
|
||||||
CRASH: DOSBox crashes on startup!.
|
CRASH: DOSBox crashes on startup!.
|
||||||
Look at Section 11: Troubleshooting
|
Look at Section 11: "Troubleshooting".
|
||||||
|
|
||||||
|
|
||||||
GAME: My Build game(Duke3D/Blood/Shadow Warrior) has problems.
|
GAME: My Build game(Duke3D/Blood/Shadow Warrior) has problems.
|
||||||
@ -395,7 +396,7 @@ SAFETY: Can DOSBox harm my computer?
|
|||||||
|
|
||||||
|
|
||||||
OPTIONS: I would like to change DOSBox's options.
|
OPTIONS: I would like to change DOSBox's options.
|
||||||
Look at Section 13. "The configuration (options) file"
|
Look at Section 13: "The configuration (options) file".
|
||||||
|
|
||||||
|
|
||||||
HELP: Great Manual, but I still don't get it.
|
HELP: Great Manual, but I still don't get it.
|
||||||
@ -412,7 +413,7 @@ HELP: Great Manual, but I still don't get it.
|
|||||||
|
|
||||||
An overview of the command line options you can give to DOSBox. Although
|
An overview of the command line options you can give to DOSBox. Although
|
||||||
in most cases it is easier to use DOSBox's configuration file instead.
|
in most cases it is easier to use DOSBox's configuration file instead.
|
||||||
See: Section 13. "The configuration (options) file"
|
See Section 13: "The configuration (options) file".
|
||||||
|
|
||||||
To be able to use Command Line Parameters:
|
To be able to use Command Line Parameters:
|
||||||
(Windows) open cmd.exe or command.com or edit the shortcut to dosbox.exe
|
(Windows) open cmd.exe or command.com or edit the shortcut to dosbox.exe
|
||||||
@ -461,11 +462,11 @@ dosbox -erasemapper
|
|||||||
-conf configfilelocation
|
-conf configfilelocation
|
||||||
Start DOSBox with the options specified in "configfilelocation".
|
Start DOSBox with the options specified in "configfilelocation".
|
||||||
Multiple -conf options may be present.
|
Multiple -conf options may be present.
|
||||||
See Section 13 for more details.
|
See Section 13: "The configuration (options) file" for more details.
|
||||||
|
|
||||||
-lang languagefilelocation
|
-lang languagefilelocation
|
||||||
Start DOSBox using the language specified in "languagefilelocation".
|
Start DOSBox using the language specified in "languagefilelocation".
|
||||||
See Section 14 for more details.
|
See Section 14: "The Language File" for more details.
|
||||||
|
|
||||||
-machine machinetype
|
-machine machinetype
|
||||||
Setup DOSBox to emulate a specific type of machine. Valid choices are:
|
Setup DOSBox to emulate a specific type of machine. Valid choices are:
|
||||||
@ -763,8 +764,8 @@ CONFIG -get "section property"
|
|||||||
config -writeconf c:\dosgames\dosbox.conf
|
config -writeconf c:\dosgames\dosbox.conf
|
||||||
2. To set the cpu cycles to 10000:
|
2. To set the cpu cycles to 10000:
|
||||||
config -set "cpu cycles=10000"
|
config -set "cpu cycles=10000"
|
||||||
3. To turn ems memory emulation off:
|
3. To turn EMS memory emulation off:
|
||||||
config -set "dos ems=off"
|
config -set "dos ems=false"
|
||||||
4. To check which cpu core is being used.
|
4. To check which cpu core is being used.
|
||||||
config -get "cpu core"
|
config -get "cpu core"
|
||||||
|
|
||||||
@ -1015,7 +1016,7 @@ IPX
|
|||||||
KEYB [keyboardlayoutcode [codepage [codepagefile]]]
|
KEYB [keyboardlayoutcode [codepage [codepagefile]]]
|
||||||
|
|
||||||
Change the keyboard layout. For detailed information about keyboard layouts
|
Change the keyboard layout. For detailed information about keyboard layouts
|
||||||
please see Section 8: "Keyboard Layout"
|
please see Section 8: "Keyboard Layout".
|
||||||
|
|
||||||
[keyboardlayoutcode] is a string consisting of five or less characters,
|
[keyboardlayoutcode] is a string consisting of five or less characters,
|
||||||
examples are PL214 (Polish typists) or PL457 (Polish programmers).
|
examples are PL214 (Polish typists) or PL457 (Polish programmers).
|
||||||
@ -1092,7 +1093,7 @@ F11 (machine=hercules) cycle through amber, green, white colouring***
|
|||||||
a different machine type. So either reassign them or reset the mapper.
|
a different machine type. So either reassign them or reset the mapper.
|
||||||
|
|
||||||
These are the default keybindings. They can be changed in the keymapper
|
These are the default keybindings. They can be changed in the keymapper
|
||||||
(see Section 7: KeyMapper).
|
(see Section 7: "KeyMapper").
|
||||||
|
|
||||||
In MAC OS you can try using cmd(applekey) together with Ctrl if the key doesn't
|
In MAC OS you can try using cmd(applekey) together with Ctrl if the key doesn't
|
||||||
work eg. cmd-ctrl-F1, but some keys may still need remapping (in Linux too).
|
work eg. cmd-ctrl-F1, but some keys may still need remapping (in Linux too).
|
||||||
@ -1146,8 +1147,8 @@ inside DOSBox, try different 'timed' setting in DOSBox's configuration file.
|
|||||||
7. KeyMapper:
|
7. KeyMapper:
|
||||||
=============
|
=============
|
||||||
|
|
||||||
You start the DOSBox mapper either with CTRL-F1 (see section 5. Special Keys)
|
You start the DOSBox mapper either with CTRL-F1 (see Section 5: "Special Keys")
|
||||||
or -startmapper (see Section 3. Command Line Parameters).
|
or -startmapper (see Section 3: "Command Line Parameters").
|
||||||
You are presented with a virtual keyboard and a virtual joystick.
|
You are presented with a virtual keyboard and a virtual joystick.
|
||||||
|
|
||||||
These virtual devices correspond to the keys and events DOSBox will
|
These virtual devices correspond to the keys and events DOSBox will
|
||||||
@ -1241,9 +1242,9 @@ your mapperfile, if it is present in the DOSBox configuration file.
|
|||||||
|
|
||||||
To switch to a different keyboard layout, either the entry "keyboardlayout"
|
To switch to a different keyboard layout, either the entry "keyboardlayout"
|
||||||
in the [dos] section of the DOSBox configuration file can be used, or the
|
in the [dos] section of the DOSBox configuration file can be used, or the
|
||||||
internal DOSBox program keyb.com (Section 4: Internal Programs)
|
internal DOSBox program keyb.com (Section 4: "Internal Programs"). Both accept
|
||||||
Both accept DOS conforming language codes (see below),
|
DOS conforming language codes (see below), but only by using keyb.com a
|
||||||
but only by using keyb.com a custom codepage can be specified.
|
custom codepage can be specified.
|
||||||
|
|
||||||
The default keyboardlayout=auto currently works under windows only. The language
|
The default keyboardlayout=auto currently works under windows only. The language
|
||||||
is chosen according to the OS language, but the keyboard layout is not detected.
|
is chosen according to the OS language, but the keyboard layout is not detected.
|
||||||
@ -1357,8 +1358,8 @@ CPU Cycles (speed up/slow down)
|
|||||||
a different setting in the DOSBox's configuration file.
|
a different setting in the DOSBox's configuration file.
|
||||||
|
|
||||||
You can force the slow or fast behavior by setting a fixed amount of cycles
|
You can force the slow or fast behavior by setting a fixed amount of cycles
|
||||||
in the DOSBox's configuration file. If you for example set cycles=10000, then
|
in the DOSBox's configuration file. If you set for example cycles=10000, the
|
||||||
DOSBox window will display a line "Cpu Speed: fixed 10000 cycles" at the top.
|
DOSBox window will display a line "CPU speed: fixed 10000 cycles" at the top.
|
||||||
In this mode you can reduce the amount of cycles even more by hitting CTRL-F11
|
In this mode you can reduce the amount of cycles even more by hitting CTRL-F11
|
||||||
(you can go as low as you want) or raise it by hitting CTRL-F12 as much as you
|
(you can go as low as you want) or raise it by hitting CTRL-F12 as much as you
|
||||||
want, but you will be limited by the power of one core of your computer's CPU.
|
want, but you will be limited by the power of one core of your computer's CPU.
|
||||||
@ -1373,8 +1374,8 @@ CPU Cycles (speed up/slow down)
|
|||||||
|
|
||||||
You can also force the fast behavior by setting cycles=max in the DOSBox
|
You can also force the fast behavior by setting cycles=max in the DOSBox
|
||||||
configuration file. The DOSBox window will display a line
|
configuration file. The DOSBox window will display a line
|
||||||
"Cpu Speed: max 100% cycles" at the top then. This time you won't have to care
|
"CPU speed: max 100% cycles" at the top then. This time you won't have to care
|
||||||
how much free time your real CPU's cores have, because DOSBox will always use
|
how much free time your real CPU cores have, because DOSBox will always use
|
||||||
100% of your real CPU's one core. In this mode you can reduce the amount
|
100% of your real CPU's one core. In this mode you can reduce the amount
|
||||||
of your real CPU's core usage by CTRL-F11 or raise it with CTRL-F12.
|
of your real CPU's core usage by CTRL-F11 or raise it with CTRL-F12.
|
||||||
|
|
||||||
@ -1424,7 +1425,7 @@ Example:
|
|||||||
====================
|
====================
|
||||||
|
|
||||||
General tip:
|
General tip:
|
||||||
Check messages in DOSBox Status Window. See section 12. "DOSBox Status Window"
|
Check messages in DOSBox Status Window. See Section 12: "DOSBox Status Window".
|
||||||
|
|
||||||
DOSBox crashes right after starting it:
|
DOSBox crashes right after starting it:
|
||||||
- use different values for the output= entry in your DOSBox
|
- use different values for the output= entry in your DOSBox
|
||||||
|
@ -114,6 +114,8 @@ DmaChannel * GetDMAChannel(Bit8u chan);
|
|||||||
void CloseSecondDMAController(void);
|
void CloseSecondDMAController(void);
|
||||||
bool SecondDMAControllerAvailable(void);
|
bool SecondDMAControllerAvailable(void);
|
||||||
|
|
||||||
|
void DMA_SetWrapping(Bitu wrap);
|
||||||
|
|
||||||
static Bit32u dma_wrapping = 0xffff;
|
static Bit32u dma_wrapping = 0xffff;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -338,7 +338,7 @@ void DOSBOX_Init(void) {
|
|||||||
const char* machines[] = {
|
const char* machines[] = {
|
||||||
"hercules", "cga", "tandy", "pcjr", "ega",
|
"hercules", "cga", "tandy", "pcjr", "ega",
|
||||||
"vgaonly", "svga_s3", "svga_et3000", "svga_et4000",
|
"vgaonly", "svga_s3", "svga_et3000", "svga_et4000",
|
||||||
"svga_paradise", "vesa_nolfb", "vesa_oldvbe", 0 };
|
"svga_paradise", "vesa_nolfb", "vesa_oldvbe", 0 };
|
||||||
secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit);
|
secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit);
|
||||||
Pstring = secprop->Add_path("language",Property::Changeable::Always,"");
|
Pstring = secprop->Add_path("language",Property::Changeable::Always,"");
|
||||||
Pstring->Set_help("Select another language file.");
|
Pstring->Set_help("Select another language file.");
|
||||||
@ -681,8 +681,13 @@ void DOSBOX_Init(void) {
|
|||||||
Pbool->Set_help("Enable XMS support.");
|
Pbool->Set_help("Enable XMS support.");
|
||||||
|
|
||||||
secprop->AddInitFunction(&EMS_Init,true);//done
|
secprop->AddInitFunction(&EMS_Init,true);//done
|
||||||
Pbool = secprop->Add_bool("ems",Property::Changeable::WhenIdle,true);
|
const char* ems_settings[] = { "true", "emsboard", "emm386", "false", 0};
|
||||||
Pbool->Set_help("Enable EMS support.");
|
Pstring = secprop->Add_string("ems",Property::Changeable::WhenIdle,"true");
|
||||||
|
Pstring->Set_values(ems_settings);
|
||||||
|
Pstring->Set_help("Enable EMS support. The default (=true) provides the best\n"
|
||||||
|
"compatibility but certain applications may run better with\n"
|
||||||
|
"other choices, or require EMS support to be disabled (=false)\n"
|
||||||
|
"to work at all.");
|
||||||
|
|
||||||
Pbool = secprop->Add_bool("umb",Property::Changeable::WhenIdle,true);
|
Pbool = secprop->Add_bool("umb",Property::Changeable::WhenIdle,true);
|
||||||
Pbool->Set_help("Enable UMB support.");
|
Pbool->Set_help("Enable UMB support.");
|
||||||
|
@ -239,9 +239,9 @@ void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused){
|
|||||||
if(cycles != -1) internal_cycles = cycles;
|
if(cycles != -1) internal_cycles = cycles;
|
||||||
if(frameskip != -1) internal_frameskip = frameskip;
|
if(frameskip != -1) internal_frameskip = frameskip;
|
||||||
if(CPU_CycleAutoAdjust) {
|
if(CPU_CycleAutoAdjust) {
|
||||||
sprintf(title,"DOSBox %s, Cpu speed: max %3d%% cycles, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram);
|
sprintf(title,"DOSBox %s, CPU speed: max %3d%% cycles, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram);
|
||||||
} else {
|
} else {
|
||||||
sprintf(title,"DOSBox %s, Cpu speed: %8d cycles, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram);
|
sprintf(title,"DOSBox %s, CPU speed: %8d cycles, Frameskip %2d, Program: %8s",VERSION,internal_cycles,internal_frameskip,RunningProgram);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(paused) strcat(title," PAUSED");
|
if(paused) strcat(title," PAUSED");
|
||||||
|
@ -48,7 +48,9 @@ static void DMA_BlockRead(PhysPt spage,PhysPt offset,void * data,Bitu size,Bit8u
|
|||||||
offset <<= dma16;
|
offset <<= dma16;
|
||||||
Bit32u dma_wrap = ((0xffff<<dma16)+dma16) | dma_wrapping;
|
Bit32u dma_wrap = ((0xffff<<dma16)+dma16) | dma_wrapping;
|
||||||
for ( ; size ; size--, offset++) {
|
for ( ; size ; size--, offset++) {
|
||||||
if (offset>(dma_wrapping<<dma16)) E_Exit("DMA segbound wrapping (read)");
|
if (offset>(dma_wrapping<<dma16)) {
|
||||||
|
LOG_MSG("DMA segbound wrapping (read): %x:%x size %x [%x] wrap %x",spage,offset,size,dma16,dma_wrapping);
|
||||||
|
}
|
||||||
offset &= dma_wrap;
|
offset &= dma_wrap;
|
||||||
Bitu page = highpart_addr_page+(offset >> 12);
|
Bitu page = highpart_addr_page+(offset >> 12);
|
||||||
/* care for EMS pageframe etc. */
|
/* care for EMS pageframe etc. */
|
||||||
@ -67,7 +69,9 @@ static void DMA_BlockWrite(PhysPt spage,PhysPt offset,void * data,Bitu size,Bit8
|
|||||||
offset <<= dma16;
|
offset <<= dma16;
|
||||||
Bit32u dma_wrap = ((0xffff<<dma16)+dma16) | dma_wrapping;
|
Bit32u dma_wrap = ((0xffff<<dma16)+dma16) | dma_wrapping;
|
||||||
for ( ; size ; size--, offset++) {
|
for ( ; size ; size--, offset++) {
|
||||||
if (offset>(dma_wrapping<<dma16)) E_Exit("DMA segbound wrapping (write)");
|
if (offset>(dma_wrapping<<dma16)) {
|
||||||
|
LOG_MSG("DMA segbound wrapping (write): %x:%x size %x [%x] wrap %x",spage,offset,size,dma16,dma_wrapping);
|
||||||
|
}
|
||||||
offset &= dma_wrap;
|
offset &= dma_wrap;
|
||||||
Bitu page = highpart_addr_page+(offset >> 12);
|
Bitu page = highpart_addr_page+(offset >> 12);
|
||||||
/* care for EMS pageframe etc. */
|
/* care for EMS pageframe etc. */
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: hardware.cpp,v 1.23 2009-10-11 18:09:22 qbix79 Exp $ */
|
/* $Id: hardware.cpp,v 1.22 2009-04-26 18:24:36 qbix79 Exp $ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -161,13 +161,17 @@ static void CAPTURE_AddAviChunk(const char * tag, Bit32u size, void * data, Bit3
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (C_SSHOT)
|
#if (C_SSHOT)
|
||||||
|
static void CAPTURE_VideoEvent(bool pressed) {
|
||||||
|
if (!pressed)
|
||||||
|
return;
|
||||||
|
if (CaptureState & CAPTURE_VIDEO) {
|
||||||
|
/* Close the video */
|
||||||
|
CaptureState &= ~CAPTURE_VIDEO;
|
||||||
|
LOG_MSG("Stopped capturing video.");
|
||||||
|
|
||||||
static void CAPTURE_VideoHeader() {
|
|
||||||
Bit8u avi_header[AVI_HEADER_SIZE];
|
Bit8u avi_header[AVI_HEADER_SIZE];
|
||||||
Bitu main_list;
|
Bitu main_list;
|
||||||
Bitu header_pos=0;
|
Bitu header_pos=0;
|
||||||
Bitu save_pos=ftell(capture.video.handle);
|
|
||||||
|
|
||||||
#define AVIOUT4(_S_) memcpy(&avi_header[header_pos],_S_,4);header_pos+=4;
|
#define AVIOUT4(_S_) memcpy(&avi_header[header_pos],_S_,4);header_pos+=4;
|
||||||
#define AVIOUTw(_S_) host_writew(&avi_header[header_pos], _S_);header_pos+=2;
|
#define AVIOUTw(_S_) host_writew(&avi_header[header_pos], _S_);header_pos+=2;
|
||||||
#define AVIOUTd(_S_) host_writed(&avi_header[header_pos], _S_);header_pos+=4;
|
#define AVIOUTd(_S_) host_writed(&avi_header[header_pos], _S_);header_pos+=4;
|
||||||
@ -284,20 +288,6 @@ static void CAPTURE_VideoHeader() {
|
|||||||
fwrite( capture.video.index, 1, capture.video.indexused, capture.video.handle);
|
fwrite( capture.video.index, 1, capture.video.indexused, capture.video.handle);
|
||||||
fseek(capture.video.handle, 0, SEEK_SET);
|
fseek(capture.video.handle, 0, SEEK_SET);
|
||||||
fwrite(&avi_header, 1, AVI_HEADER_SIZE, capture.video.handle);
|
fwrite(&avi_header, 1, AVI_HEADER_SIZE, capture.video.handle);
|
||||||
fseek(capture.video.handle, save_pos, SEEK_SET);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CAPTURE_VideoEvent(bool pressed) {
|
|
||||||
if (!pressed)
|
|
||||||
return;
|
|
||||||
if (CaptureState & CAPTURE_VIDEO) {
|
|
||||||
/* Close the video */
|
|
||||||
CaptureState &= ~CAPTURE_VIDEO;
|
|
||||||
LOG_MSG("Stopped capturing video.");
|
|
||||||
|
|
||||||
/* Adds AVI header to the file */
|
|
||||||
CAPTURE_VideoHeader();
|
|
||||||
|
|
||||||
fclose( capture.video.handle );
|
fclose( capture.video.handle );
|
||||||
free( capture.video.index );
|
free( capture.video.index );
|
||||||
free( capture.video.buf );
|
free( capture.video.buf );
|
||||||
@ -557,9 +547,6 @@ skip_shot:
|
|||||||
capture.video.audioused = 0;
|
capture.video.audioused = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adds AVI header to the file */
|
|
||||||
CAPTURE_VideoHeader();
|
|
||||||
|
|
||||||
/* Everything went okay, set flag again for next frame */
|
/* Everything went okay, set flag again for next frame */
|
||||||
CaptureState |= CAPTURE_VIDEO;
|
CaptureState |= CAPTURE_VIDEO;
|
||||||
}
|
}
|
||||||
@ -756,6 +743,9 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
~HARDWARE(){
|
~HARDWARE(){
|
||||||
|
#if (C_SSHOT)
|
||||||
|
if (capture.video.handle) CAPTURE_VideoEvent(true);
|
||||||
|
#endif
|
||||||
if (capture.wave.handle) CAPTURE_WaveEvent(true);
|
if (capture.wave.handle) CAPTURE_WaveEvent(true);
|
||||||
if (capture.midi.handle) CAPTURE_MidiEvent(true);
|
if (capture.midi.handle) CAPTURE_MidiEvent(true);
|
||||||
}
|
}
|
||||||
|
@ -118,30 +118,30 @@ static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart, Bitu line) {
|
|||||||
|
|
||||||
static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart, Bitu line) {
|
static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart, Bitu line) {
|
||||||
const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
|
const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
|
||||||
Bit32u * draw=(Bit32u *)TempLine;
|
Bit8u* draw=TempLine;
|
||||||
for (Bitu x=0;x<vga.draw.blocks;x++) {
|
Bitu end = vga.draw.blocks*2;
|
||||||
Bitu val1 = base[vidstart & vga.tandy.addr_mask];
|
while(end) {
|
||||||
++vidstart;
|
Bit8u byte = base[vidstart & vga.tandy.addr_mask];
|
||||||
Bitu val2 = base[vidstart & vga.tandy.addr_mask];
|
*draw++=vga.attr.palette[byte >> 4];
|
||||||
++vidstart;
|
*draw++=vga.attr.palette[byte & 0x0f];
|
||||||
*draw++=(val1 & 0x0f) << 8 |
|
vidstart++;
|
||||||
(val1 & 0xf0) >> 4 |
|
end--;
|
||||||
(val2 & 0x0f) << 24 |
|
|
||||||
(val2 & 0xf0) << 12;
|
|
||||||
}
|
}
|
||||||
return TempLine;
|
return TempLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart, Bitu line) {
|
static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart, Bitu line) {
|
||||||
const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
|
const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
|
||||||
Bit32u * draw=(Bit32u *)TempLine;
|
Bit8u* draw=TempLine;
|
||||||
for (Bitu x=0;x<vga.draw.blocks;x++) {
|
Bitu end = vga.draw.blocks;
|
||||||
Bitu val = base[vidstart & vga.tandy.addr_mask];
|
while(end) {
|
||||||
++vidstart;
|
Bit8u byte = base[vidstart & vga.tandy.addr_mask];
|
||||||
*draw++=(val & 0xf0) >> 4 |
|
Bit8u data = vga.attr.palette[byte >> 4];
|
||||||
(val & 0xf0) << 4 |
|
*draw++ = data; *draw++ = data;
|
||||||
(val & 0x0f) << 16 |
|
data = vga.attr.palette[byte & 0x0f];
|
||||||
(val & 0x0f) << 24;
|
*draw++ = data; *draw++ = data;
|
||||||
|
vidstart++;
|
||||||
|
end--;
|
||||||
}
|
}
|
||||||
return TempLine;
|
return TempLine;
|
||||||
}
|
}
|
||||||
@ -175,12 +175,28 @@ static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu /*line*/) {
|
static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu /*line*/) {
|
||||||
// There is guaranteed extra memory past the wrap boundary. So, instead of using temporary
|
|
||||||
// storage just copy appropriate chunk from the beginning to the wrap boundary when needed.
|
|
||||||
Bitu offset = vidstart & vga.draw.linear_mask;
|
Bitu offset = vidstart & vga.draw.linear_mask;
|
||||||
if (vga.draw.linear_mask-offset < vga.draw.line_length)
|
Bit8u* ret = &vga.draw.linear_base[offset];
|
||||||
memcpy(vga.draw.linear_base+vga.draw.linear_mask+1, vga.draw.linear_base, vga.draw.line_length);
|
|
||||||
Bit8u *ret = &vga.draw.linear_base[ offset ];
|
// in case (vga.draw.line_length + offset) has bits set that
|
||||||
|
// are not set in the mask: ((x|y)!=y) equals (x&~y)
|
||||||
|
if (GCC_UNLIKELY((vga.draw.line_length + offset)& ~vga.draw.linear_mask)) {
|
||||||
|
// this happens, if at all, only once per frame (1 of 480 lines)
|
||||||
|
// in some obscure games
|
||||||
|
Bitu end = (offset + vga.draw.line_length) & vga.draw.linear_mask;
|
||||||
|
|
||||||
|
// assuming lines not longer than 4096 pixels
|
||||||
|
Bitu wrapped_len = end & 0xFFF;
|
||||||
|
Bitu unwrapped_len = vga.draw.line_length-wrapped_len;
|
||||||
|
|
||||||
|
// unwrapped chunk: to top of memory block
|
||||||
|
memcpy(TempLine, &vga.draw.linear_base[offset], unwrapped_len);
|
||||||
|
// wrapped chunk: from base of memory block
|
||||||
|
memcpy(&TempLine[unwrapped_len], vga.draw.linear_base, wrapped_len);
|
||||||
|
|
||||||
|
ret = TempLine;
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(C_UNALIGNED_MEMORY)
|
#if !defined(C_UNALIGNED_MEMORY)
|
||||||
if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) {
|
if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) {
|
||||||
memcpy( TempLine, ret, vga.draw.line_length );
|
memcpy( TempLine, ret, vga.draw.line_length );
|
||||||
@ -589,10 +605,60 @@ static void VGA_ProcessSplit() {
|
|||||||
vga.draw.address_line=0;
|
vga.draw.address_line=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Bit8u bg_color_index = 0; // screen-off black index
|
||||||
static void VGA_DrawSingleLine(Bitu /*blah*/) {
|
static void VGA_DrawSingleLine(Bitu /*blah*/) {
|
||||||
if (GCC_UNLIKELY(vga.attr.disabled)) {
|
if (GCC_UNLIKELY(vga.attr.disabled)) {
|
||||||
// draw blanked line (DoWhackaDo, Alien Carnage, TV sports Football)
|
switch(machine) {
|
||||||
memset(TempLine, 0, sizeof(TempLine));
|
case MCH_PCJR:
|
||||||
|
// Displays the border color when screen is disabled
|
||||||
|
bg_color_index = vga.tandy.border_color;
|
||||||
|
break;
|
||||||
|
case MCH_TANDY:
|
||||||
|
// Either the PCJr way or the CGA way
|
||||||
|
if (vga.tandy.gfx_control& 0x4) {
|
||||||
|
bg_color_index = vga.tandy.border_color;
|
||||||
|
} else if (vga.mode==M_TANDY4)
|
||||||
|
bg_color_index = vga.attr.palette[0];
|
||||||
|
else bg_color_index = 0;
|
||||||
|
break;
|
||||||
|
case MCH_CGA:
|
||||||
|
// the background color
|
||||||
|
bg_color_index = vga.attr.overscan_color;
|
||||||
|
break;
|
||||||
|
case MCH_EGA:
|
||||||
|
case MCH_VGA:
|
||||||
|
// DoWhackaDo, Alien Carnage, TV sports Football
|
||||||
|
// when disabled by attribute index bit 5:
|
||||||
|
// ET3000, ET4000, Paradise display the border color
|
||||||
|
// S3 displays the content of the currently selected attribute register
|
||||||
|
// when disabled by sequencer the screen is black "257th color"
|
||||||
|
|
||||||
|
// the DAC table may not match the bits of the overscan register
|
||||||
|
// so use black for this case too...
|
||||||
|
//if (vga.attr.disabled& 2) {
|
||||||
|
if (vga.dac.xlat16[bg_color_index] != 0) {
|
||||||
|
for(Bitu i = 0; i < 256; i++)
|
||||||
|
if (vga.dac.xlat16[i] == 0) {
|
||||||
|
bg_color_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//} else
|
||||||
|
// bg_color_index = vga.attr.overscan_color;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bg_color_index = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (vga.draw.bpp==8) {
|
||||||
|
memset(TempLine, bg_color_index, sizeof(TempLine));
|
||||||
|
} else if (vga.draw.bpp==16) {
|
||||||
|
Bit16u* wptr = (Bit16u*) TempLine;
|
||||||
|
Bit16u value = vga.dac.xlat16[bg_color_index];
|
||||||
|
for (Bitu i = 0; i < sizeof(TempLine)/2; i++) {
|
||||||
|
wptr[i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
RENDER_DrawLine(TempLine);
|
RENDER_DrawLine(TempLine);
|
||||||
} else {
|
} else {
|
||||||
Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line );
|
Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line );
|
||||||
@ -966,6 +1032,7 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
|||||||
switch (machine) {
|
switch (machine) {
|
||||||
case MCH_CGA:
|
case MCH_CGA:
|
||||||
case MCH_PCJR:
|
case MCH_PCJR:
|
||||||
|
case MCH_TANDY:
|
||||||
vga.draw.mode = LINE;
|
vga.draw.mode = LINE;
|
||||||
break;
|
break;
|
||||||
case MCH_EGA:
|
case MCH_EGA:
|
||||||
|
@ -153,6 +153,27 @@ static Bitu read_crtc_data_other(Bitu /*port*/,Bitu /*iolen*/) {
|
|||||||
return (Bitu)(~0);
|
return (Bitu)(~0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void write_lightpen(Bitu port,Bitu val,Bitu) {
|
||||||
|
switch (port) {
|
||||||
|
case 0x3db: // Clear lightpen latch
|
||||||
|
vga.other.lightpen_triggered = false;
|
||||||
|
break;
|
||||||
|
case 0x3dc: // Preset lightpen latch
|
||||||
|
if (!vga.other.lightpen_triggered) {
|
||||||
|
vga.other.lightpen_triggered = true; // TODO: this shows at port 3ba/3da bit 1
|
||||||
|
|
||||||
|
double timeInFrame = PIC_FullIndex()-vga.draw.delay.framestart;
|
||||||
|
double timeInLine = fmod(timeInFrame,vga.draw.delay.htotal);
|
||||||
|
Bitu current_scanline = (Bitu)(timeInFrame / vga.draw.delay.htotal);
|
||||||
|
|
||||||
|
vga.other.lightpen = (Bit16u)((vga.draw.address_add/2) * (current_scanline/2));
|
||||||
|
vga.other.lightpen += (Bit16u)((timeInLine / vga.draw.delay.hdend) *
|
||||||
|
((float)(vga.draw.address_add/2)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static double hue_offset = 0.0;
|
static double hue_offset = 0.0;
|
||||||
static Bit8u cga16_val = 0;
|
static Bit8u cga16_val = 0;
|
||||||
static void update_cga16_color(void);
|
static void update_cga16_color(void);
|
||||||
@ -235,56 +256,139 @@ static void DecreaseHue(bool pressed) {
|
|||||||
LOG_MSG("Hue at %f",hue_offset);
|
LOG_MSG("Hue at %f",hue_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_color_select(Bit8u val) {
|
static void write_cga_color_select(Bitu val) {
|
||||||
vga.tandy.color_select=val;
|
vga.tandy.color_select=val;
|
||||||
switch (vga.mode) {
|
switch(vga.mode) {
|
||||||
|
case M_TANDY4: {
|
||||||
|
Bit8u base = (val & 0x10) ? 0x08 : 0;
|
||||||
|
Bit8u bg = val & 0xf;
|
||||||
|
if (vga.tandy.mode_control & 0x4) // cyan red white
|
||||||
|
VGA_SetCGA4Table(bg, 3+base, 4+base, 7+base);
|
||||||
|
else if (val & 0x20) // cyan magenta white
|
||||||
|
VGA_SetCGA4Table(bg, 3+base, 5+base, 7+base);
|
||||||
|
else // green red brown
|
||||||
|
VGA_SetCGA4Table(bg, 2+base, 4+base, 6+base);
|
||||||
|
vga.tandy.border_color = bg;
|
||||||
|
vga.attr.overscan_color = bg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case M_TANDY2:
|
case M_TANDY2:
|
||||||
VGA_SetCGA2Table(0,val & 0xf);
|
VGA_SetCGA2Table(0,val & 0xf);
|
||||||
break;
|
vga.attr.overscan_color = 0;
|
||||||
case M_TANDY4:
|
|
||||||
{
|
|
||||||
if ((machine==MCH_TANDY && (vga.tandy.gfx_control & 0x8)) ||
|
|
||||||
(machine==MCH_PCJR && (vga.tandy.mode_control==0x0b))) {
|
|
||||||
VGA_SetCGA4Table(0,1,2,3);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Bit8u base=(val & 0x10) ? 0x08 : 0;
|
|
||||||
/* Check for BW Mode */
|
|
||||||
if (vga.tandy.mode_control & 0x4) {
|
|
||||||
VGA_SetCGA4Table(val & 0xf,3+base,4+base,7+base);
|
|
||||||
} else {
|
|
||||||
if (val & 0x20) VGA_SetCGA4Table(val & 0xf,3+base,5+base,7+base);
|
|
||||||
else VGA_SetCGA4Table(val & 0xf,2+base,4+base,6+base);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case M_CGA16:
|
case M_CGA16:
|
||||||
cga16_color_select(val);
|
cga16_color_select(val);
|
||||||
break;
|
break;
|
||||||
case M_TEXT:
|
case M_TEXT:
|
||||||
case M_TANDY16:
|
vga.tandy.border_color = val & 0xf;
|
||||||
|
vga.attr.overscan_color = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TANDY_FindMode(void) {
|
static void write_cga(Bitu port,Bitu val,Bitu /*iolen*/) {
|
||||||
if (vga.tandy.mode_control & 0x2) {
|
switch (port) {
|
||||||
if (vga.tandy.gfx_control & 0x10)
|
case 0x3d8:
|
||||||
VGA_SetMode(M_TANDY16);
|
vga.tandy.mode_control=(Bit8u)val;
|
||||||
else if (vga.tandy.gfx_control & 0x08)
|
vga.attr.disabled = (val&0x8)? 0: 1;
|
||||||
VGA_SetMode(M_TANDY4);
|
if (vga.tandy.mode_control & 0x2) { // graphics mode
|
||||||
else if (vga.tandy.mode_control & 0x10)
|
if (vga.tandy.mode_control & 0x10) {// highres mode
|
||||||
VGA_SetMode(M_TANDY2);
|
if (!(val & 0x4)) { // burst on
|
||||||
else
|
VGA_SetMode(M_CGA16); // composite ntsc 160x200 16 color mode
|
||||||
VGA_SetMode(M_TANDY4);
|
} else {
|
||||||
write_color_select(vga.tandy.color_select);
|
VGA_SetMode(M_TANDY2);
|
||||||
|
}
|
||||||
|
} else VGA_SetMode(M_TANDY4); // lowres mode
|
||||||
|
|
||||||
|
write_cga_color_select(vga.tandy.color_select);
|
||||||
|
} else {
|
||||||
|
VGA_SetMode(M_TANDY_TEXT);
|
||||||
|
}
|
||||||
|
VGA_SetBlinking(val & 0x20);
|
||||||
|
break;
|
||||||
|
case 0x3d9: // color select
|
||||||
|
write_cga_color_select(val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tandy_update_palette() {
|
||||||
|
// TODO mask off bits if needed
|
||||||
|
if (machine == MCH_TANDY) {
|
||||||
|
switch (vga.mode) {
|
||||||
|
case M_TANDY2:
|
||||||
|
VGA_SetCGA2Table(vga.attr.palette[0],
|
||||||
|
//vga.attr.palette[vga.tandy.color_select&0xf]);
|
||||||
|
vga.attr.palette[0xf]);
|
||||||
|
//VGA_SetCGA2Table(vga.attr.palette[0xf],vga.attr.palette[0]);
|
||||||
|
break;
|
||||||
|
case M_TANDY4:
|
||||||
|
if (vga.tandy.gfx_control & 0x8) {
|
||||||
|
// 4-color high resolution - might be an idea to introduce M_TANDY4H
|
||||||
|
VGA_SetCGA4Table( // function sets both medium and highres 4color tables
|
||||||
|
vga.attr.palette[0], vga.attr.palette[1],
|
||||||
|
vga.attr.palette[2], vga.attr.palette[3]);
|
||||||
|
} else {
|
||||||
|
Bit8u color_set = 0;
|
||||||
|
Bit8u r_mask = 0xf;
|
||||||
|
if (vga.tandy.color_select & 0x10) color_set |= 8; // intensity
|
||||||
|
if (vga.tandy.color_select & 0x20) color_set |= 1; // Cyan Mag. White
|
||||||
|
if (vga.tandy.mode_control & 0x04) { // Cyan Red White
|
||||||
|
color_set |= 1;
|
||||||
|
r_mask &= ~1;
|
||||||
|
}
|
||||||
|
VGA_SetCGA4Table(
|
||||||
|
vga.attr.palette[0],
|
||||||
|
vga.attr.palette[(2|color_set)& vga.tandy.palette_mask],
|
||||||
|
vga.attr.palette[(4|(color_set& r_mask))& vga.tandy.palette_mask],
|
||||||
|
vga.attr.palette[(6|color_set)& vga.tandy.palette_mask]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
VGA_SetMode(M_TANDY_TEXT);
|
// PCJr
|
||||||
|
switch (vga.mode) {
|
||||||
|
case M_TANDY2:
|
||||||
|
VGA_SetCGA2Table(vga.attr.palette[0],vga.attr.palette[1]);
|
||||||
|
break;
|
||||||
|
case M_TANDY4:
|
||||||
|
VGA_SetCGA4Table(
|
||||||
|
vga.attr.palette[0], vga.attr.palette[1],
|
||||||
|
vga.attr.palette[2], vga.attr.palette[3]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VGA_SetModeNow(VGAModes mode);
|
void VGA_SetModeNow(VGAModes mode);
|
||||||
|
|
||||||
|
static void TANDY_FindMode(void) {
|
||||||
|
if (vga.tandy.mode_control & 0x2) {
|
||||||
|
if (vga.tandy.gfx_control & 0x10) {
|
||||||
|
if (vga.mode==M_TANDY4) {
|
||||||
|
VGA_SetModeNow(M_TANDY16);
|
||||||
|
} else VGA_SetMode(M_TANDY16);
|
||||||
|
}
|
||||||
|
else if (vga.tandy.gfx_control & 0x08) {
|
||||||
|
VGA_SetMode(M_TANDY4);
|
||||||
|
}
|
||||||
|
else if (vga.tandy.mode_control & 0x10)
|
||||||
|
VGA_SetMode(M_TANDY2);
|
||||||
|
else {
|
||||||
|
if (vga.mode==M_TANDY16) {
|
||||||
|
VGA_SetModeNow(M_TANDY4);
|
||||||
|
} else VGA_SetMode(M_TANDY4);
|
||||||
|
}
|
||||||
|
tandy_update_palette();
|
||||||
|
} else {
|
||||||
|
VGA_SetMode(M_TANDY_TEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void PCJr_FindMode(void) {
|
static void PCJr_FindMode(void) {
|
||||||
if (vga.tandy.mode_control & 0x2) {
|
if (vga.tandy.mode_control & 0x2) {
|
||||||
if (vga.tandy.mode_control & 0x10) {
|
if (vga.tandy.mode_control & 0x10) {
|
||||||
@ -299,7 +403,6 @@ static void PCJr_FindMode(void) {
|
|||||||
if (vga.mode==M_TANDY16) VGA_SetModeNow(M_TANDY4);
|
if (vga.mode==M_TANDY16) VGA_SetModeNow(M_TANDY4);
|
||||||
else VGA_SetMode(M_TANDY4);
|
else VGA_SetMode(M_TANDY4);
|
||||||
}
|
}
|
||||||
write_color_select(vga.tandy.color_select);
|
|
||||||
} else {
|
} else {
|
||||||
VGA_SetMode(M_TANDY_TEXT);
|
VGA_SetMode(M_TANDY_TEXT);
|
||||||
}
|
}
|
||||||
@ -327,11 +430,16 @@ static void write_tandy_reg(Bit8u val) {
|
|||||||
vga.tandy.mode_control=val;
|
vga.tandy.mode_control=val;
|
||||||
VGA_SetBlinking(val & 0x20);
|
VGA_SetBlinking(val & 0x20);
|
||||||
PCJr_FindMode();
|
PCJr_FindMode();
|
||||||
vga.attr.disabled = (val&0x8)? 0: 1;
|
if (val&0x8) vga.attr.disabled &= ~1;
|
||||||
|
else vga.attr.disabled |= 1;
|
||||||
} else {
|
} else {
|
||||||
LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index);
|
LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 0x1: /* Palette mask */
|
||||||
|
vga.tandy.palette_mask = val;
|
||||||
|
tandy_update_palette();
|
||||||
|
break;
|
||||||
case 0x2: /* Border color */
|
case 0x2: /* Border color */
|
||||||
vga.tandy.border_color=val;
|
vga.tandy.border_color=val;
|
||||||
break;
|
break;
|
||||||
@ -348,45 +456,12 @@ static void write_tandy_reg(Bit8u val) {
|
|||||||
TandyCheckLineMask();
|
TandyCheckLineMask();
|
||||||
VGA_SetupHandlers();
|
VGA_SetupHandlers();
|
||||||
break;
|
break;
|
||||||
case 0x8: /* Monitor mode seletion */
|
default:
|
||||||
//Bit 1 select mode e, for 640x200x16, some double clocking thing?
|
if ((vga.tandy.reg_index & 0xf0) == 0x10) { // color palette
|
||||||
//Bit 4 select 350 line mode for hercules emulation
|
vga.attr.palette[vga.tandy.reg_index-0x10] = val&0xf;
|
||||||
LOG(LOG_VGAMISC,LOG_NORMAL)("Write %2X to tandy monitor mode",val );
|
tandy_update_palette();
|
||||||
break;
|
} else
|
||||||
/* palette colors */
|
LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index);
|
||||||
case 0x10: case 0x11: case 0x12: case 0x13:
|
|
||||||
case 0x14: case 0x15: case 0x16: case 0x17:
|
|
||||||
case 0x18: case 0x19: case 0x1a: case 0x1b:
|
|
||||||
case 0x1c: case 0x1d: case 0x1e: case 0x1f:
|
|
||||||
VGA_ATTR_SetPalette(vga.tandy.reg_index-0x10,val & 0xf);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_cga(Bitu port,Bitu val,Bitu /*iolen*/) {
|
|
||||||
switch (port) {
|
|
||||||
case 0x3d8:
|
|
||||||
vga.tandy.mode_control=(Bit8u)val;
|
|
||||||
vga.attr.disabled = (val&0x8)? 0: 1;
|
|
||||||
if (vga.tandy.mode_control & 0x2) {
|
|
||||||
if (vga.tandy.mode_control & 0x10) {
|
|
||||||
if (!(val & 0x4) && machine==MCH_CGA) {
|
|
||||||
VGA_SetMode(M_CGA16); //Video burst 16 160x200 color mode
|
|
||||||
} else {
|
|
||||||
VGA_SetMode(M_TANDY2);
|
|
||||||
}
|
|
||||||
} else VGA_SetMode(M_TANDY4);
|
|
||||||
write_color_select(vga.tandy.color_select);
|
|
||||||
} else {
|
|
||||||
VGA_SetMode(M_TANDY_TEXT);
|
|
||||||
}
|
|
||||||
VGA_SetBlinking(val & 0x20);
|
|
||||||
break;
|
|
||||||
case 0x3d9:
|
|
||||||
write_color_select((Bit8u)val);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,40 +469,32 @@ static void write_tandy(Bitu port,Bitu val,Bitu /*iolen*/) {
|
|||||||
switch (port) {
|
switch (port) {
|
||||||
case 0x3d8:
|
case 0x3d8:
|
||||||
vga.tandy.mode_control=(Bit8u)val;
|
vga.tandy.mode_control=(Bit8u)val;
|
||||||
|
if (val&0x8) vga.attr.disabled &= ~1;
|
||||||
|
else vga.attr.disabled |= 1;
|
||||||
TandyCheckLineMask();
|
TandyCheckLineMask();
|
||||||
VGA_SetBlinking(val & 0x20);
|
VGA_SetBlinking(val & 0x20);
|
||||||
TANDY_FindMode();
|
TANDY_FindMode();
|
||||||
break;
|
break;
|
||||||
case 0x3d9:
|
case 0x3d9:
|
||||||
write_color_select((Bit8u)val);
|
vga.tandy.color_select=val;
|
||||||
|
if (vga.mode==M_TANDY2) vga.attr.palette[0xf] = vga.tandy.color_select&0xf;
|
||||||
|
else vga.attr.palette[0] = vga.tandy.color_select&0xf; // Pirates!
|
||||||
|
tandy_update_palette();
|
||||||
break;
|
break;
|
||||||
case 0x3da:
|
case 0x3da:
|
||||||
vga.tandy.reg_index=(Bit8u)val;
|
vga.tandy.reg_index=(Bit8u)val;
|
||||||
break;
|
//if (val&0x10) vga.attr.disabled |= 2;
|
||||||
case 0x3db: // Clear lightpen latch
|
//else vga.attr.disabled &= ~2;
|
||||||
vga.other.lightpen_triggered = false;
|
|
||||||
break;
|
|
||||||
case 0x3dc: // Preset lightpen latch
|
|
||||||
if (!vga.other.lightpen_triggered) {
|
|
||||||
vga.other.lightpen_triggered = true; // TODO: this shows at port 3ba/3da bit 1
|
|
||||||
|
|
||||||
double timeInFrame = PIC_FullIndex()-vga.draw.delay.framestart;
|
|
||||||
double timeInLine = fmod(timeInFrame,vga.draw.delay.htotal);
|
|
||||||
Bitu current_scanline = (Bitu)(timeInFrame / vga.draw.delay.htotal);
|
|
||||||
|
|
||||||
vga.other.lightpen = (Bit16u)((vga.draw.address_add/2) * (current_scanline/2));
|
|
||||||
vga.other.lightpen += (Bit16u)((timeInLine / vga.draw.delay.hdend) *
|
|
||||||
((float)(vga.draw.address_add/2)));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
// case 0x3dd: //Extended ram page address register:
|
// case 0x3dd: //Extended ram page address register:
|
||||||
break;
|
// break;
|
||||||
case 0x3de:
|
case 0x3de:
|
||||||
write_tandy_reg((Bit8u)val);
|
write_tandy_reg((Bit8u)val);
|
||||||
break;
|
break;
|
||||||
case 0x3df:
|
case 0x3df:
|
||||||
vga.tandy.line_mask = (Bit8u)(val >> 6);
|
vga.tandy.line_mask = (Bit8u)(val >> 6);
|
||||||
vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7);
|
vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7);
|
||||||
|
if(vga.tandy.line_mask==3) vga.tandy.draw_bank &= ~1; // LSB unused in 32k modes
|
||||||
vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7);
|
vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7);
|
||||||
TandyCheckLineMask();
|
TandyCheckLineMask();
|
||||||
VGA_SetupHandlers();
|
VGA_SetupHandlers();
|
||||||
@ -437,12 +504,14 @@ static void write_tandy(Bitu port,Bitu val,Bitu /*iolen*/) {
|
|||||||
|
|
||||||
static void write_pcjr(Bitu port,Bitu val,Bitu /*iolen*/) {
|
static void write_pcjr(Bitu port,Bitu val,Bitu /*iolen*/) {
|
||||||
switch (port) {
|
switch (port) {
|
||||||
case 0x3d9:
|
|
||||||
write_color_select((Bit8u)val);
|
|
||||||
break;
|
|
||||||
case 0x3da:
|
case 0x3da:
|
||||||
if (vga.tandy.pcjr_flipflop) write_tandy_reg((Bit8u)val);
|
if (vga.tandy.pcjr_flipflop) write_tandy_reg((Bit8u)val);
|
||||||
else vga.tandy.reg_index=(Bit8u)val;
|
else {
|
||||||
|
vga.tandy.reg_index=(Bit8u)val;
|
||||||
|
if (vga.tandy.reg_index & 0x10)
|
||||||
|
vga.attr.disabled |= 2;
|
||||||
|
else vga.attr.disabled &= ~2;
|
||||||
|
}
|
||||||
vga.tandy.pcjr_flipflop=!vga.tandy.pcjr_flipflop;
|
vga.tandy.pcjr_flipflop=!vga.tandy.pcjr_flipflop;
|
||||||
break;
|
break;
|
||||||
case 0x3df:
|
case 0x3df:
|
||||||
@ -577,6 +646,10 @@ void VGA_SetupOther(void) {
|
|||||||
for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_08[i*8],8);
|
for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_08[i*8],8);
|
||||||
vga.draw.font_tables[0]=vga.draw.font_tables[1]=vga.draw.font;
|
vga.draw.font_tables[0]=vga.draw.font_tables[1]=vga.draw.font;
|
||||||
}
|
}
|
||||||
|
if (machine==MCH_CGA || IS_TANDY_ARCH || machine==MCH_HERC) {
|
||||||
|
IO_RegisterWriteHandler(0x3db,write_lightpen,IO_MB);
|
||||||
|
IO_RegisterWriteHandler(0x3dc,write_lightpen,IO_MB);
|
||||||
|
}
|
||||||
if (machine==MCH_HERC) {
|
if (machine==MCH_HERC) {
|
||||||
extern Bit8u int10_font_14[256 * 14];
|
extern Bit8u int10_font_14[256 * 14];
|
||||||
for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_14[i*14],14);
|
for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_14[i*14],14);
|
||||||
@ -586,8 +659,6 @@ void VGA_SetupOther(void) {
|
|||||||
if (machine==MCH_CGA) {
|
if (machine==MCH_CGA) {
|
||||||
IO_RegisterWriteHandler(0x3d8,write_cga,IO_MB);
|
IO_RegisterWriteHandler(0x3d8,write_cga,IO_MB);
|
||||||
IO_RegisterWriteHandler(0x3d9,write_cga,IO_MB);
|
IO_RegisterWriteHandler(0x3d9,write_cga,IO_MB);
|
||||||
IO_RegisterWriteHandler(0x3db,write_tandy,IO_MB);
|
|
||||||
IO_RegisterWriteHandler(0x3dc,write_tandy,IO_MB);
|
|
||||||
MAPPER_AddHandler(IncreaseHue,MK_f11,MMOD2,"inchue","Inc Hue");
|
MAPPER_AddHandler(IncreaseHue,MK_f11,MMOD2,"inchue","Inc Hue");
|
||||||
MAPPER_AddHandler(DecreaseHue,MK_f11,0,"dechue","Dec Hue");
|
MAPPER_AddHandler(DecreaseHue,MK_f11,0,"dechue","Dec Hue");
|
||||||
}
|
}
|
||||||
@ -595,14 +666,13 @@ void VGA_SetupOther(void) {
|
|||||||
write_tandy( 0x3df, 0x0, 0 );
|
write_tandy( 0x3df, 0x0, 0 );
|
||||||
IO_RegisterWriteHandler(0x3d8,write_tandy,IO_MB);
|
IO_RegisterWriteHandler(0x3d8,write_tandy,IO_MB);
|
||||||
IO_RegisterWriteHandler(0x3d9,write_tandy,IO_MB);
|
IO_RegisterWriteHandler(0x3d9,write_tandy,IO_MB);
|
||||||
|
IO_RegisterWriteHandler(0x3da,write_tandy,IO_MB);
|
||||||
IO_RegisterWriteHandler(0x3de,write_tandy,IO_MB);
|
IO_RegisterWriteHandler(0x3de,write_tandy,IO_MB);
|
||||||
IO_RegisterWriteHandler(0x3df,write_tandy,IO_MB);
|
IO_RegisterWriteHandler(0x3df,write_tandy,IO_MB);
|
||||||
IO_RegisterWriteHandler(0x3da,write_tandy,IO_MB);
|
|
||||||
}
|
}
|
||||||
if (machine==MCH_PCJR) {
|
if (machine==MCH_PCJR) {
|
||||||
//write_pcjr will setup base address
|
//write_pcjr will setup base address
|
||||||
write_pcjr( 0x3df, 0x7 | (0x7 << 3), 0 );
|
write_pcjr( 0x3df, 0x7 | (0x7 << 3), 0 );
|
||||||
IO_RegisterWriteHandler(0x3d9,write_pcjr,IO_MB);
|
|
||||||
IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB);
|
IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB);
|
||||||
IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB);
|
IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB);
|
||||||
}
|
}
|
||||||
|
@ -434,18 +434,16 @@ static Bitu INT17_Handler(void) {
|
|||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bit8u INT14_Wait(Bit16u port, Bit8u mask, Bit8u timeout) {
|
static bool INT14_Wait(Bit16u port, Bit8u mask, Bit8u timeout, Bit8u* retval) {
|
||||||
double starttime = PIC_FullIndex();
|
double starttime = PIC_FullIndex();
|
||||||
double timeout_f = timeout * 1000.0;
|
double timeout_f = timeout * 1000.0;
|
||||||
Bit8u retval;
|
while (((*retval = IO_ReadB(port)) & mask) != mask) {
|
||||||
while (((retval = IO_ReadB(port)) & mask) != mask) {
|
|
||||||
if (starttime < (PIC_FullIndex() - timeout_f)) {
|
if (starttime < (PIC_FullIndex() - timeout_f)) {
|
||||||
retval |= 0x80;
|
return false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
CALLBACK_Idle();
|
CALLBACK_Idle();
|
||||||
}
|
}
|
||||||
return retval;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bitu INT14_Handler(void) {
|
static Bitu INT14_Handler(void) {
|
||||||
@ -500,7 +498,7 @@ static Bitu INT14_Handler(void) {
|
|||||||
CALLBACK_SCF(false);
|
CALLBACK_SCF(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x01: { // Transmit character
|
case 0x01: // Transmit character
|
||||||
// Parameters: Return:
|
// Parameters: Return:
|
||||||
// AL: character AL: unchanged
|
// AL: character AL: unchanged
|
||||||
// AH: 0x01 AH: line status from just before the char was sent
|
// AH: 0x01 AH: line status from just before the char was sent
|
||||||
@ -510,20 +508,19 @@ static Bitu INT14_Handler(void) {
|
|||||||
|
|
||||||
// set DTR & RTS on
|
// set DTR & RTS on
|
||||||
IO_WriteB(port+4,0x3);
|
IO_WriteB(port+4,0x3);
|
||||||
|
|
||||||
// wait for DSR & CTS
|
// wait for DSR & CTS
|
||||||
reg_ah = INT14_Wait(port+6, 0x30, timeout);
|
if (INT14_Wait(port+6, 0x30, timeout, ®_ah)) {
|
||||||
if (!(reg_ah & 0x80)) {
|
|
||||||
// wait for TX buffer empty
|
// wait for TX buffer empty
|
||||||
reg_ah = INT14_Wait(port+5, 0x20, timeout);
|
if (INT14_Wait(port+5, 0x20, timeout, ®_ah)) {
|
||||||
if (!(reg_ah & 0x80)) {
|
|
||||||
// fianlly send the character
|
// fianlly send the character
|
||||||
IO_WriteB(port,reg_al);
|
IO_WriteB(port,reg_al);
|
||||||
}
|
} else
|
||||||
} // else timed out
|
reg_ah |= 0x80;
|
||||||
|
} else // timed out
|
||||||
|
reg_ah |= 0x80;
|
||||||
|
|
||||||
CALLBACK_SCF(false);
|
CALLBACK_SCF(false);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case 0x02: // Read character
|
case 0x02: // Read character
|
||||||
// Parameters: Return:
|
// Parameters: Return:
|
||||||
// AH: 0x02 AL: received character
|
// AH: 0x02 AL: received character
|
||||||
@ -537,15 +534,16 @@ static Bitu INT14_Handler(void) {
|
|||||||
IO_WriteB(port+4,0x1);
|
IO_WriteB(port+4,0x1);
|
||||||
|
|
||||||
// wait for DSR
|
// wait for DSR
|
||||||
reg_ah = INT14_Wait(port+6, 0x20, timeout);
|
if (INT14_Wait(port+6, 0x20, timeout, ®_ah)) {
|
||||||
if (!(reg_ah & 0x80)) {
|
|
||||||
// wait for character to arrive
|
// wait for character to arrive
|
||||||
reg_ah = INT14_Wait(port+5, 0x01, timeout);
|
if (INT14_Wait(port+5, 0x01, timeout, ®_ah)) {
|
||||||
if (!(reg_ah & 0x80)) {
|
|
||||||
reg_ah &= 0x1E;
|
reg_ah &= 0x1E;
|
||||||
reg_al = IO_ReadB(port);
|
reg_al = IO_ReadB(port);
|
||||||
}
|
} else
|
||||||
}
|
reg_ah |= 0x80;
|
||||||
|
} else
|
||||||
|
reg_ah |= 0x80;
|
||||||
|
|
||||||
CALLBACK_SCF(false);
|
CALLBACK_SCF(false);
|
||||||
break;
|
break;
|
||||||
case 0x03: // get status
|
case 0x03: // get status
|
||||||
|
139
src/ints/ems.cpp
139
src/ints/ems.cpp
@ -32,6 +32,7 @@
|
|||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
#include "dma.h"
|
||||||
|
|
||||||
#define EMM_PAGEFRAME 0xE000
|
#define EMM_PAGEFRAME 0xE000
|
||||||
#define EMM_PAGEFRAME4K ((EMM_PAGEFRAME*16)/4096)
|
#define EMM_PAGEFRAME4K ((EMM_PAGEFRAME*16)/4096)
|
||||||
@ -88,6 +89,8 @@ struct EMM_Handle {
|
|||||||
EMM_Mapping page_map[EMM_MAX_PHYS];
|
EMM_Mapping page_map[EMM_MAX_PHYS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Bitu ems_type;
|
||||||
|
|
||||||
static EMM_Handle emm_handles[EMM_MAX_HANDLES];
|
static EMM_Handle emm_handles[EMM_MAX_HANDLES];
|
||||||
static EMM_Mapping emm_mappings[EMM_MAX_PHYS];
|
static EMM_Mapping emm_mappings[EMM_MAX_PHYS];
|
||||||
static EMM_Mapping emm_segmentmappings[0x40];
|
static EMM_Mapping emm_segmentmappings[0x40];
|
||||||
@ -97,7 +100,8 @@ static Bit16u GEMMIS_seg;
|
|||||||
|
|
||||||
class device_EMM : public DOS_Device {
|
class device_EMM : public DOS_Device {
|
||||||
public:
|
public:
|
||||||
device_EMM() {
|
device_EMM(bool is_emm386_avail) {
|
||||||
|
is_emm386=is_emm386_avail;
|
||||||
SetName("EMMXXXX0");
|
SetName("EMMXXXX0");
|
||||||
GEMMIS_seg=0;
|
GEMMIS_seg=0;
|
||||||
}
|
}
|
||||||
@ -108,11 +112,12 @@ public:
|
|||||||
}
|
}
|
||||||
bool Seek(Bit32u * /*pos*/,Bit32u /*type*/){return false;}
|
bool Seek(Bit32u * /*pos*/,Bit32u /*type*/){return false;}
|
||||||
bool Close(){return false;}
|
bool Close(){return false;}
|
||||||
Bit16u GetInformation(void){return 0xc080;}
|
Bit16u GetInformation(void){return 0xc0c0;}
|
||||||
bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode);
|
bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode);
|
||||||
bool WriteToControlChannel(PhysPt /*bufptr*/,Bit16u /*size*/,Bit16u * /*retcode*/){return true;}
|
bool WriteToControlChannel(PhysPt /*bufptr*/,Bit16u /*size*/,Bit16u * /*retcode*/){return true;}
|
||||||
private:
|
private:
|
||||||
Bit8u cache;
|
Bit8u cache;
|
||||||
|
bool is_emm386;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) {
|
bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) {
|
||||||
@ -125,6 +130,7 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco
|
|||||||
*retcode=6;
|
*retcode=6;
|
||||||
return true;
|
return true;
|
||||||
case 0x01: {
|
case 0x01: {
|
||||||
|
if (!is_emm386) return false;
|
||||||
if (size!=6) return false;
|
if (size!=6) return false;
|
||||||
if (GEMMIS_seg==0) GEMMIS_seg=DOS_GetMemory(0x20);
|
if (GEMMIS_seg==0) GEMMIS_seg=DOS_GetMemory(0x20);
|
||||||
PhysPt GEMMIS_addr=PhysMake(GEMMIS_seg,0);
|
PhysPt GEMMIS_addr=PhysMake(GEMMIS_seg,0);
|
||||||
@ -181,12 +187,14 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case 0x02:
|
case 0x02:
|
||||||
|
if (!is_emm386) return false;
|
||||||
if (size!=2) return false;
|
if (size!=2) return false;
|
||||||
mem_writeb(bufptr+0x00,EMM_VERSION>>4); // version 4
|
mem_writeb(bufptr+0x00,EMM_VERSION>>4); // version 4
|
||||||
mem_writeb(bufptr+0x01,EMM_MINOR_VERSION);
|
mem_writeb(bufptr+0x01,EMM_MINOR_VERSION);
|
||||||
*retcode=2;
|
*retcode=2;
|
||||||
return true;
|
return true;
|
||||||
case 0x03:
|
case 0x03:
|
||||||
|
if (!is_emm386) return false;
|
||||||
if (EMM_MINOR_VERSION < 0x2d) return false;
|
if (EMM_MINOR_VERSION < 0x2d) return false;
|
||||||
if (size!=4) return false;
|
if (size!=4) return false;
|
||||||
mem_writew(bufptr+0x00,(Bit16u)(MEM_TotalPages()*4)); // max size (kb)
|
mem_writew(bufptr+0x00,(Bit16u)(MEM_TotalPages()*4)); // max size (kb)
|
||||||
@ -323,7 +331,23 @@ static Bit8u EMM_MapPage(Bitu phys_page,Bit16u handle,Bit16u log_page) {
|
|||||||
static Bit8u EMM_MapSegment(Bitu segment,Bit16u handle,Bit16u log_page) {
|
static Bit8u EMM_MapSegment(Bitu segment,Bit16u handle,Bit16u log_page) {
|
||||||
// LOG_MSG("EMS MapSegment handle %d segment %d log %d",handle,segment,log_page);
|
// LOG_MSG("EMS MapSegment handle %d segment %d log %d",handle,segment,log_page);
|
||||||
|
|
||||||
if (((segment>=0xa000) && (segment<0xb000)) || ((segment>=EMM_PAGEFRAME-0x1000) && (segment<EMM_PAGEFRAME+0x1000))) {
|
bool valid_segment=false;
|
||||||
|
|
||||||
|
if ((ems_type==1) || (ems_type==3)) {
|
||||||
|
if (segment<0xf000+0x1000) valid_segment=true;
|
||||||
|
} else {
|
||||||
|
if ((segment>=0xa000) && (segment<0xb000)) {
|
||||||
|
valid_segment=true; // allow mapping of graphics memory
|
||||||
|
}
|
||||||
|
if ((segment>=EMM_PAGEFRAME) && (segment<EMM_PAGEFRAME+0x1000)) {
|
||||||
|
valid_segment=true; // allow mapping of EMS page frame
|
||||||
|
}
|
||||||
|
/* if ((segment>=EMM_PAGEFRAME-0x1000) && (segment<EMM_PAGEFRAME)) {
|
||||||
|
valid_segment=true;
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_segment) {
|
||||||
Bit32s tphysPage = ((Bit32s)segment-EMM_PAGEFRAME)/(0x1000/EMM_MAX_PHYS);
|
Bit32s tphysPage = ((Bit32s)segment-EMM_PAGEFRAME)/(0x1000/EMM_MAX_PHYS);
|
||||||
|
|
||||||
/* unmapping doesn't need valid handle (as handle isn't used) */
|
/* unmapping doesn't need valid handle (as handle isn't used) */
|
||||||
@ -1262,9 +1286,25 @@ static Bitu INT4B_Handler() {
|
|||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bitu GetEMSType(Section_prop * section) {
|
||||||
|
Bitu rtype = 0;
|
||||||
|
std::string emstypestr(section->Get_string("ems"));
|
||||||
|
if (emstypestr=="true") {
|
||||||
|
rtype = 1; // mixed mode
|
||||||
|
} else if (emstypestr=="emsboard") {
|
||||||
|
rtype = 2;
|
||||||
|
} else if (emstypestr=="emm386") {
|
||||||
|
rtype = 3;
|
||||||
|
} else {
|
||||||
|
rtype = 0;
|
||||||
|
}
|
||||||
|
return rtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class EMS: public Module_base {
|
class EMS: public Module_base {
|
||||||
private:
|
private:
|
||||||
|
DOS_Device * emm_device;
|
||||||
/* location in protected unfreeable memory where the ems name and callback are
|
/* location in protected unfreeable memory where the ems name and callback are
|
||||||
* stored 32 bytes.*/
|
* stored 32 bytes.*/
|
||||||
static Bit16u ems_baseseg;
|
static Bit16u ems_baseseg;
|
||||||
@ -1273,7 +1313,9 @@ private:
|
|||||||
Bitu call_int67;
|
Bitu call_int67;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EMS(Section* configuration):Module_base(configuration){
|
EMS(Section* configuration):Module_base(configuration) {
|
||||||
|
emm_device=NULL;
|
||||||
|
ems_type=0;
|
||||||
|
|
||||||
/* Virtual DMA interrupt callback */
|
/* Virtual DMA interrupt callback */
|
||||||
call_vdma.Install(&INT4B_Handler,CB_IRET,"Int 4b vdma");
|
call_vdma.Install(&INT4B_Handler,CB_IRET,"Int 4b vdma");
|
||||||
@ -1283,8 +1325,11 @@ public:
|
|||||||
GEMMIS_seg=0;
|
GEMMIS_seg=0;
|
||||||
|
|
||||||
Section_prop * section=static_cast<Section_prop *>(configuration);
|
Section_prop * section=static_cast<Section_prop *>(configuration);
|
||||||
if (!section->Get_bool("ems")) return;
|
ems_type=GetEMSType(section);
|
||||||
|
if (ems_type<=0) return;
|
||||||
|
|
||||||
if (machine==MCH_PCJR) {
|
if (machine==MCH_PCJR) {
|
||||||
|
ems_type=0;
|
||||||
LOG_MSG("EMS disabled for PCJr machine");
|
LOG_MSG("EMS disabled for PCJr machine");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1302,8 +1347,8 @@ public:
|
|||||||
|
|
||||||
/* Register the ems device */
|
/* Register the ems device */
|
||||||
//TODO MAYBE put it in the class.
|
//TODO MAYBE put it in the class.
|
||||||
DOS_Device * newdev = new device_EMM();
|
emm_device = new device_EMM(ems_type!=2);
|
||||||
DOS_AddDevice(newdev);
|
DOS_AddDevice(emm_device);
|
||||||
|
|
||||||
/* Clear handle and page tables */
|
/* Clear handle and page tables */
|
||||||
Bitu i;
|
Bitu i;
|
||||||
@ -1323,61 +1368,67 @@ public:
|
|||||||
|
|
||||||
EMM_AllocateSystemHandle(8); // allocate OS-dedicated handle (ems handle zero, 128kb)
|
EMM_AllocateSystemHandle(8); // allocate OS-dedicated handle (ems handle zero, 128kb)
|
||||||
|
|
||||||
|
if (ems_type==3) {
|
||||||
|
DMA_SetWrapping(0xffffffff); // emm386-bug that disables dma wrapping
|
||||||
|
}
|
||||||
|
|
||||||
if (!ENABLE_VCPI) return;
|
if (!ENABLE_VCPI) return;
|
||||||
|
|
||||||
/* Install a callback that handles VCPI-requests in protected mode requests */
|
if (ems_type!=2) {
|
||||||
call_vcpi.Install(&VCPI_PM_Handler,CB_IRETD,"VCPI PM");
|
/* Install a callback that handles VCPI-requests in protected mode requests */
|
||||||
vcpi.pm_interface=(call_vcpi.Get_callback())*CB_SIZE;
|
call_vcpi.Install(&VCPI_PM_Handler,CB_IRETD,"VCPI PM");
|
||||||
|
vcpi.pm_interface=(call_vcpi.Get_callback())*CB_SIZE;
|
||||||
|
|
||||||
/* Initialize private data area and set up descriptor tables */
|
/* Initialize private data area and set up descriptor tables */
|
||||||
SetupVCPI();
|
SetupVCPI();
|
||||||
|
|
||||||
if (!vcpi.enabled) return;
|
if (!vcpi.enabled) return;
|
||||||
|
|
||||||
/* Install v86-callback that handles interrupts occuring
|
/* Install v86-callback that handles interrupts occuring
|
||||||
in v86 mode, including protection fault exceptions */
|
in v86 mode, including protection fault exceptions */
|
||||||
call_v86mon.Install(&V86_Monitor,CB_IRET,"V86 Monitor");
|
call_v86mon.Install(&V86_Monitor,CB_IRET,"V86 Monitor");
|
||||||
|
|
||||||
mem_writeb(vcpi.private_area+0x2e00,(Bit8u)0xFE); //GRP 4
|
mem_writeb(vcpi.private_area+0x2e00,(Bit8u)0xFE); //GRP 4
|
||||||
mem_writeb(vcpi.private_area+0x2e01,(Bit8u)0x38); //Extra Callback instruction
|
mem_writeb(vcpi.private_area+0x2e01,(Bit8u)0x38); //Extra Callback instruction
|
||||||
mem_writew(vcpi.private_area+0x2e02,call_v86mon.Get_callback()); //The immediate word
|
mem_writew(vcpi.private_area+0x2e02,call_v86mon.Get_callback()); //The immediate word
|
||||||
mem_writeb(vcpi.private_area+0x2e04,(Bit8u)0x66);
|
mem_writeb(vcpi.private_area+0x2e04,(Bit8u)0x66);
|
||||||
mem_writeb(vcpi.private_area+0x2e05,(Bit8u)0xCF); //A IRETD Instruction
|
mem_writeb(vcpi.private_area+0x2e05,(Bit8u)0xCF); //A IRETD Instruction
|
||||||
|
|
||||||
/* Testcode only, starts up dosbox in v86-mode */
|
/* Testcode only, starts up dosbox in v86-mode */
|
||||||
if (ENABLE_V86_STARTUP) {
|
if (ENABLE_V86_STARTUP) {
|
||||||
/* Prepare V86-task */
|
/* Prepare V86-task */
|
||||||
CPU_SET_CRX(0, 1);
|
CPU_SET_CRX(0, 1);
|
||||||
CPU_LGDT(0xff, vcpi.private_area+0x0000);
|
CPU_LGDT(0xff, vcpi.private_area+0x0000);
|
||||||
CPU_LIDT(0x7ff, vcpi.private_area+0x2000);
|
CPU_LIDT(0x7ff, vcpi.private_area+0x2000);
|
||||||
if (CPU_LLDT(0x08)) LOG_MSG("VCPI:Could not load LDT");
|
if (CPU_LLDT(0x08)) LOG_MSG("VCPI:Could not load LDT");
|
||||||
if (CPU_LTR(0x10)) LOG_MSG("VCPI:Could not load TR");
|
if (CPU_LTR(0x10)) LOG_MSG("VCPI:Could not load TR");
|
||||||
|
|
||||||
CPU_Push32(SegValue(gs));
|
CPU_Push32(SegValue(gs));
|
||||||
CPU_Push32(SegValue(fs));
|
CPU_Push32(SegValue(fs));
|
||||||
CPU_Push32(SegValue(ds));
|
CPU_Push32(SegValue(ds));
|
||||||
CPU_Push32(SegValue(es));
|
CPU_Push32(SegValue(es));
|
||||||
CPU_Push32(SegValue(ss));
|
CPU_Push32(SegValue(ss));
|
||||||
CPU_Push32(0x23002);
|
CPU_Push32(0x23002);
|
||||||
CPU_Push32(SegValue(cs));
|
CPU_Push32(SegValue(cs));
|
||||||
CPU_Push32(reg_eip&0xffff);
|
CPU_Push32(reg_eip&0xffff);
|
||||||
/* Switch to V86-mode */
|
/* Switch to V86-mode */
|
||||||
cpu.cpl=0;
|
cpu.cpl=0;
|
||||||
CPU_IRET(true,0);
|
CPU_IRET(true,0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~EMS() {
|
~EMS() {
|
||||||
Section_prop * section=static_cast<Section_prop *>(m_configuration);
|
if (ems_type<=0) return;
|
||||||
if (!section->Get_bool("ems")) return;
|
|
||||||
|
|
||||||
/* Undo Biosclearing */
|
/* Undo Biosclearing */
|
||||||
BIOS_ZeroExtendedSize(false);
|
BIOS_ZeroExtendedSize(false);
|
||||||
|
|
||||||
/* Remove ems device */
|
/* Remove ems device */
|
||||||
device_EMM newdev;
|
if (emm_device!=NULL) {
|
||||||
DOS_DelDevice(&newdev);
|
DOS_DelDevice(emm_device);
|
||||||
|
emm_device=NULL;
|
||||||
|
}
|
||||||
GEMMIS_seg=0;
|
GEMMIS_seg=0;
|
||||||
|
|
||||||
/* Remove the emsname and callback hack */
|
/* Remove the emsname and callback hack */
|
||||||
|
@ -107,7 +107,9 @@ static Bitu INT10_Handler(void) {
|
|||||||
INT10_ReadCharAttr(®_ax,reg_bh);
|
INT10_ReadCharAttr(®_ax,reg_bh);
|
||||||
break;
|
break;
|
||||||
case 0x09: /* Write Character & Attribute at cursor CX times */
|
case 0x09: /* Write Character & Attribute at cursor CX times */
|
||||||
INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,true);
|
if (real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)==0x11)
|
||||||
|
INT10_WriteChar(reg_al,(reg_bl&0x80)|0x3f,reg_bh,reg_cx,true);
|
||||||
|
else INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,true);
|
||||||
break;
|
break;
|
||||||
case 0x0A: /* Write Character at cursor CX times */
|
case 0x0A: /* Write Character at cursor CX times */
|
||||||
INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,false);
|
INT10_WriteChar(reg_al,reg_bl,reg_bh,reg_cx,false);
|
||||||
@ -138,7 +140,8 @@ static Bitu INT10_Handler(void) {
|
|||||||
reg_ah=(Bit8u)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
reg_ah=(Bit8u)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
||||||
break;
|
break;
|
||||||
case 0x10: /* Palette functions */
|
case 0x10: /* Palette functions */
|
||||||
if ((machine==MCH_CGA) || ((!IS_VGA_ARCH) && (reg_al>0x03))) break;
|
if (!IS_EGAVGA_ARCH && (reg_al>0x02)) break;
|
||||||
|
else if (!IS_VGA_ARCH && (reg_al>0x03)) break;
|
||||||
switch (reg_al) {
|
switch (reg_al) {
|
||||||
case 0x00: /* SET SINGLE PALETTE REGISTER */
|
case 0x00: /* SET SINGLE PALETTE REGISTER */
|
||||||
INT10_SetSinglePaletteRegister(reg_bl,reg_bh);
|
INT10_SetSinglePaletteRegister(reg_bl,reg_bh);
|
||||||
@ -162,7 +165,7 @@ static Bitu INT10_Handler(void) {
|
|||||||
INT10_GetAllPaletteRegisters(SegPhys(es)+reg_dx);
|
INT10_GetAllPaletteRegisters(SegPhys(es)+reg_dx);
|
||||||
break;
|
break;
|
||||||
case 0x10: /* SET INDIVIDUAL DAC REGISTER */
|
case 0x10: /* SET INDIVIDUAL DAC REGISTER */
|
||||||
INT10_SetSingleDacRegister(reg_bl,reg_dh,reg_ch,reg_cl);
|
INT10_SetSingleDACRegister(reg_bl,reg_dh,reg_ch,reg_cl);
|
||||||
break;
|
break;
|
||||||
case 0x12: /* SET BLOCK OF DAC REGISTERS */
|
case 0x12: /* SET BLOCK OF DAC REGISTERS */
|
||||||
INT10_SetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx);
|
INT10_SetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx);
|
||||||
@ -171,7 +174,7 @@ static Bitu INT10_Handler(void) {
|
|||||||
INT10_SelectDACPage(reg_bl,reg_bh);
|
INT10_SelectDACPage(reg_bl,reg_bh);
|
||||||
break;
|
break;
|
||||||
case 0x15: /* GET INDIVIDUAL DAC REGISTER */
|
case 0x15: /* GET INDIVIDUAL DAC REGISTER */
|
||||||
INT10_GetSingleDacRegister(reg_bl,®_dh,®_ch,®_cl);
|
INT10_GetSingleDACRegister(reg_bl,®_dh,®_ch,®_cl);
|
||||||
break;
|
break;
|
||||||
case 0x17: /* GET BLOCK OF DAC REGISTER */
|
case 0x17: /* GET BLOCK OF DAC REGISTER */
|
||||||
INT10_GetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx);
|
INT10_GetDACBlock(reg_bx,reg_cx,SegPhys(es)+reg_dx);
|
||||||
@ -208,11 +211,11 @@ static Bitu INT10_Handler(void) {
|
|||||||
break;
|
break;
|
||||||
case 0x01: /* Load 8x14 font */
|
case 0x01: /* Load 8x14 font */
|
||||||
case 0x11:
|
case 0x11:
|
||||||
INT10_LoadFont(Real2Phys(int10.rom.font_14),reg_al==0x11,256,0,0,14);
|
INT10_LoadFont(Real2Phys(int10.rom.font_14),reg_al==0x11,256,0,reg_bl,14);
|
||||||
break;
|
break;
|
||||||
case 0x02: /* Load 8x8 font */
|
case 0x02: /* Load 8x8 font */
|
||||||
case 0x12:
|
case 0x12:
|
||||||
INT10_LoadFont(Real2Phys(int10.rom.font_8_first),reg_al==0x12,256,0,0,8);
|
INT10_LoadFont(Real2Phys(int10.rom.font_8_first),reg_al==0x12,256,0,reg_bl,8);
|
||||||
break;
|
break;
|
||||||
case 0x03: /* Set Block Specifier */
|
case 0x03: /* Set Block Specifier */
|
||||||
IO_Write(0x3c4,0x3);IO_Write(0x3c5,reg_bl);
|
IO_Write(0x3c4,0x3);IO_Write(0x3c5,reg_bl);
|
||||||
@ -220,7 +223,7 @@ static Bitu INT10_Handler(void) {
|
|||||||
case 0x04: /* Load 8x16 font */
|
case 0x04: /* Load 8x16 font */
|
||||||
case 0x14:
|
case 0x14:
|
||||||
if (!IS_VGA_ARCH) break;
|
if (!IS_VGA_ARCH) break;
|
||||||
INT10_LoadFont(Real2Phys(int10.rom.font_16),reg_al==0x14,256,0,0,16);
|
INT10_LoadFont(Real2Phys(int10.rom.font_16),reg_al==0x14,256,0,reg_bl,16);
|
||||||
break;
|
break;
|
||||||
/* Graphics mode calls */
|
/* Graphics mode calls */
|
||||||
case 0x20: /* Set User 8x8 Graphics characters */
|
case 0x20: /* Set User 8x8 Graphics characters */
|
||||||
|
@ -187,8 +187,8 @@ void INT10_ToggleBlinkingBit(Bit8u state);
|
|||||||
void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val);
|
void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val);
|
||||||
void INT10_GetOverscanBorderColor(Bit8u * val);
|
void INT10_GetOverscanBorderColor(Bit8u * val);
|
||||||
void INT10_GetAllPaletteRegisters(PhysPt data);
|
void INT10_GetAllPaletteRegisters(PhysPt data);
|
||||||
void INT10_SetSingleDacRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue);
|
void INT10_SetSingleDACRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue);
|
||||||
void INT10_GetSingleDacRegister(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_SetDACBlock(Bit16u index,Bit16u count,PhysPt data);
|
||||||
void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data);
|
void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data);
|
||||||
void INT10_SelectDACPage(Bit8u function,Bit8u mode);
|
void INT10_SelectDACPage(Bit8u function,Bit8u mode);
|
||||||
|
@ -246,6 +246,7 @@ VideoModeBlock ModeList_OTHER[]={
|
|||||||
{ 0x008 ,M_TANDY16,160 ,200 ,20 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,56 ,127 ,40 ,100 ,0 },
|
{ 0x008 ,M_TANDY16,160 ,200 ,20 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,56 ,127 ,40 ,100 ,0 },
|
||||||
{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 },
|
{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 },
|
||||||
{ 0x00A ,M_CGA4 ,640 ,200 ,80 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 },
|
{ 0x00A ,M_CGA4 ,640 ,200 ,80 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 },
|
||||||
|
//{ 0x00E ,M_TANDY16,640 ,200 ,80 ,25 ,8 ,8 ,8 ,0xA0000 ,0x10000 ,113 ,256 ,80 ,200 ,0 },
|
||||||
{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 },
|
{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -547,6 +548,11 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) {
|
|||||||
default:
|
default:
|
||||||
IO_WriteB(0x3de,0x0);break;
|
IO_WriteB(0x3de,0x0);break;
|
||||||
}
|
}
|
||||||
|
// write palette
|
||||||
|
for(Bitu i = 0; i < 16; i++) {
|
||||||
|
IO_WriteB(0x3da,i+0x10);
|
||||||
|
IO_WriteB(0x3de,i);
|
||||||
|
}
|
||||||
//Clear extended mapping
|
//Clear extended mapping
|
||||||
IO_WriteB(0x3da,0x5);
|
IO_WriteB(0x3da,0x5);
|
||||||
IO_WriteB(0x3de,0x0);
|
IO_WriteB(0x3de,0x0);
|
||||||
@ -587,8 +593,9 @@ bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) {
|
|||||||
|
|
||||||
if (CurMode->mode == 0x6 || CurMode->mode==0xa) color_select=0x3f;
|
if (CurMode->mode == 0x6 || CurMode->mode==0xa) color_select=0x3f;
|
||||||
else color_select=0x30;
|
else color_select=0x30;
|
||||||
IO_WriteB(0x3d9,color_select);
|
|
||||||
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select);
|
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select);
|
||||||
|
INT10_SetColorSelect(1);
|
||||||
|
INT10_SetBackgroundBorder(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,9 +35,44 @@ static INLINE void WriteTandyACTL(Bit8u creg,Bit8u val) {
|
|||||||
|
|
||||||
void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) {
|
void INT10_SetSinglePaletteRegister(Bit8u reg,Bit8u val) {
|
||||||
switch (machine) {
|
switch (machine) {
|
||||||
case TANDY_ARCH_CASE:
|
case MCH_PCJR:
|
||||||
|
reg&=0xf;
|
||||||
IO_Read(VGAREG_TDY_RESET);
|
IO_Read(VGAREG_TDY_RESET);
|
||||||
WriteTandyACTL(reg+0x10,val);
|
WriteTandyACTL(reg+0x10,val);
|
||||||
|
IO_Write(0x3da,0x0); // palette back on
|
||||||
|
break;
|
||||||
|
case MCH_TANDY:
|
||||||
|
// TODO waits for vertical retrace
|
||||||
|
switch(vga.mode) {
|
||||||
|
case M_TANDY2:
|
||||||
|
if (reg >= 0x10) break;
|
||||||
|
else if (reg==1) reg = 0x1f;
|
||||||
|
else reg |= 0x10;
|
||||||
|
WriteTandyACTL(reg+0x10,val);
|
||||||
|
break;
|
||||||
|
case M_TANDY4: {
|
||||||
|
if (CurMode->mode!=0x0a) {
|
||||||
|
// Palette values are kept constand by the BIOS.
|
||||||
|
// The four colors are mapped to special palette values by hardware.
|
||||||
|
// 3D8/3D9 registers influence this mapping. We need to figure out
|
||||||
|
// which entry is used for the requested color.
|
||||||
|
if (reg > 3) break;
|
||||||
|
if (reg != 0) { // 0 is assumed to be at 0
|
||||||
|
Bit8u color_select=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL);
|
||||||
|
reg = reg*2+8; // Green Red Brown
|
||||||
|
if (color_select& 0x20) reg++; // Cyan Magenta White
|
||||||
|
}
|
||||||
|
WriteTandyACTL(reg+0x10,val);
|
||||||
|
}
|
||||||
|
// 4-color high resolution mode 0x0a isn't handled specially
|
||||||
|
else WriteTandyACTL(reg+0x10,val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
WriteTandyACTL(reg+0x10,val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
IO_Write(0x3da,0x0); // palette back on
|
||||||
break;
|
break;
|
||||||
case EGAVGA_ARCH_CASE:
|
case EGAVGA_ARCH_CASE:
|
||||||
if (!IS_VGA_ARCH) reg&=0x1f;
|
if (!IS_VGA_ARCH) reg&=0x1f;
|
||||||
@ -168,14 +203,23 @@ void INT10_GetAllPaletteRegisters(PhysPt data) {
|
|||||||
ResetACTL();
|
ResetACTL();
|
||||||
}
|
}
|
||||||
|
|
||||||
void INT10_SetSingleDacRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue) {
|
void INT10_SetSingleDACRegister(Bit8u index,Bit8u red,Bit8u green,Bit8u blue) {
|
||||||
IO_Write(VGAREG_DAC_WRITE_ADDRESS,(Bit8u)index);
|
IO_Write(VGAREG_DAC_WRITE_ADDRESS,(Bit8u)index);
|
||||||
IO_Write(VGAREG_DAC_DATA,red);
|
if ((real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x06)==0) {
|
||||||
IO_Write(VGAREG_DAC_DATA,green);
|
IO_Write(VGAREG_DAC_DATA,red);
|
||||||
IO_Write(VGAREG_DAC_DATA,blue);
|
IO_Write(VGAREG_DAC_DATA,green);
|
||||||
|
IO_Write(VGAREG_DAC_DATA,blue);
|
||||||
|
} else {
|
||||||
|
/* calculate clamped intensity, taken from VGABIOS */
|
||||||
|
Bit32u i=(( 77*red + 151*green + 28*blue ) + 0x80) >> 8;
|
||||||
|
Bit8u ic=(i>0x3f) ? 0x3f : ((Bit8u)(i & 0xff));
|
||||||
|
IO_Write(VGAREG_DAC_DATA,ic);
|
||||||
|
IO_Write(VGAREG_DAC_DATA,ic);
|
||||||
|
IO_Write(VGAREG_DAC_DATA,ic);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * blue) {
|
void INT10_GetSingleDACRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * blue) {
|
||||||
IO_Write(VGAREG_DAC_READ_ADDRESS,index);
|
IO_Write(VGAREG_DAC_READ_ADDRESS,index);
|
||||||
*red=IO_Read(VGAREG_DAC_DATA);
|
*red=IO_Read(VGAREG_DAC_DATA);
|
||||||
*green=IO_Read(VGAREG_DAC_DATA);
|
*green=IO_Read(VGAREG_DAC_DATA);
|
||||||
@ -184,10 +228,25 @@ void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * bl
|
|||||||
|
|
||||||
void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data) {
|
void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data) {
|
||||||
IO_Write(VGAREG_DAC_WRITE_ADDRESS,(Bit8u)index);
|
IO_Write(VGAREG_DAC_WRITE_ADDRESS,(Bit8u)index);
|
||||||
for (;count>0;count--) {
|
if ((real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x06)==0) {
|
||||||
IO_Write(VGAREG_DAC_DATA,mem_readb(data++));
|
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++));
|
IO_Write(VGAREG_DAC_DATA,mem_readb(data++));
|
||||||
|
IO_Write(VGAREG_DAC_DATA,mem_readb(data++));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (;count>0;count--) {
|
||||||
|
Bit8u red=mem_readb(data++);
|
||||||
|
Bit8u green=mem_readb(data++);
|
||||||
|
Bit8u blue=mem_readb(data++);
|
||||||
|
|
||||||
|
/* calculate clamped intensity, taken from VGABIOS */
|
||||||
|
Bit32u i=(( 77*red + 151*green + 28*blue ) + 0x80) >> 8;
|
||||||
|
Bit8u ic=(i>0x3f) ? 0x3f : ((Bit8u)(i & 0xff));
|
||||||
|
IO_Write(VGAREG_DAC_DATA,ic);
|
||||||
|
IO_Write(VGAREG_DAC_DATA,ic);
|
||||||
|
IO_Write(VGAREG_DAC_DATA,ic);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,14 +301,24 @@ void INT10_SetPelMask(Bit8u mask) {
|
|||||||
|
|
||||||
void INT10_GetPelMask(Bit8u & mask) {
|
void INT10_GetPelMask(Bit8u & mask) {
|
||||||
mask=IO_Read(VGAREG_PEL_MASK);
|
mask=IO_Read(VGAREG_PEL_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void INT10_SetBackgroundBorder(Bit8u val) {
|
void INT10_SetBackgroundBorder(Bit8u val) {
|
||||||
Bit8u temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL);
|
Bit8u color_select=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL);
|
||||||
temp=(temp & 0xe0) | (val & 0x1f);
|
color_select=(color_select & 0xe0) | (val & 0x1f);
|
||||||
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp);
|
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select);
|
||||||
if (machine == MCH_CGA || IS_TANDY_ARCH)
|
|
||||||
IO_Write(0x3d9,temp);
|
if (machine == MCH_CGA || machine == MCH_TANDY)
|
||||||
|
IO_Write(0x3d9,color_select);
|
||||||
|
else if (machine == MCH_PCJR) {
|
||||||
|
IO_Read(VGAREG_TDY_RESET); // reset the flipflop
|
||||||
|
if (vga.mode!=M_TANDY_TEXT) {
|
||||||
|
IO_Write(VGAREG_TDY_ADDRESS, 0x10);
|
||||||
|
IO_Write(VGAREG_PCJR_DATA, color_select&0xf);
|
||||||
|
}
|
||||||
|
IO_Write(VGAREG_TDY_ADDRESS, 0x2); // border color
|
||||||
|
IO_Write(VGAREG_PCJR_DATA, color_select&0xf);
|
||||||
|
}
|
||||||
else if (IS_EGAVGA_ARCH) {
|
else if (IS_EGAVGA_ARCH) {
|
||||||
val = ((val << 1) & 0x10) | (val & 0x7);
|
val = ((val << 1) & 0x10) | (val & 0x7);
|
||||||
/* Aways set the overscan color */
|
/* Aways set the overscan color */
|
||||||
@ -258,7 +327,7 @@ void INT10_SetBackgroundBorder(Bit8u val) {
|
|||||||
if (CurMode->mode <= 3)
|
if (CurMode->mode <= 3)
|
||||||
return;
|
return;
|
||||||
INT10_SetSinglePaletteRegister( 0, val );
|
INT10_SetSinglePaletteRegister( 0, val );
|
||||||
val = (temp & 0x10) | 2 | ((temp & 0x20) >> 5);
|
val = (color_select & 0x10) | 2 | ((color_select & 0x20) >> 5);
|
||||||
INT10_SetSinglePaletteRegister( 1, val );
|
INT10_SetSinglePaletteRegister( 1, val );
|
||||||
val+=2;
|
val+=2;
|
||||||
INT10_SetSinglePaletteRegister( 2, val );
|
INT10_SetSinglePaletteRegister( 2, val );
|
||||||
@ -271,8 +340,31 @@ void INT10_SetColorSelect(Bit8u val) {
|
|||||||
Bit8u temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL);
|
Bit8u temp=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL);
|
||||||
temp=(temp & 0xdf) | ((val & 1) ? 0x20 : 0x0);
|
temp=(temp & 0xdf) | ((val & 1) ? 0x20 : 0x0);
|
||||||
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp);
|
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,temp);
|
||||||
if (machine == MCH_CGA || IS_TANDY_ARCH)
|
if (machine == MCH_CGA || machine==MCH_TANDY)
|
||||||
IO_Write(0x3d9,temp);
|
IO_Write(0x3d9,temp);
|
||||||
|
else if (machine == MCH_PCJR) {
|
||||||
|
switch(vga.mode) {
|
||||||
|
case M_TANDY2:
|
||||||
|
IO_Write(VGAREG_TDY_ADDRESS, 0x11);
|
||||||
|
IO_Write(VGAREG_PCJR_DATA, val&1? 0xf:0);
|
||||||
|
break;
|
||||||
|
case M_TANDY4:
|
||||||
|
for(Bit8u i = 0x11; i < 0x14; i++) {
|
||||||
|
const Bit8u t4_table[] = {0,2,4,6, 0,3,5,0xf};
|
||||||
|
IO_Write(VGAREG_TDY_ADDRESS, i);
|
||||||
|
IO_Write(VGAREG_PCJR_DATA, t4_table[(i-0x10)+(val&1? 4:0)]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 16-color modes: always write the same palette
|
||||||
|
for(Bit8u i = 0x11; i < 0x20; i++) {
|
||||||
|
IO_Write(VGAREG_TDY_ADDRESS, i);
|
||||||
|
IO_Write(VGAREG_PCJR_DATA, i-0x10);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
IO_Write(VGAREG_TDY_ADDRESS, 0); // enable palette
|
||||||
|
}
|
||||||
else if (IS_EGAVGA_ARCH) {
|
else if (IS_EGAVGA_ARCH) {
|
||||||
if (CurMode->mode <= 3) //Maybe even skip the total function!
|
if (CurMode->mode <= 3) //Maybe even skip the total function!
|
||||||
return;
|
return;
|
||||||
@ -296,6 +388,6 @@ void INT10_PerformGrayScaleSumming(Bit16u start_reg,Bit16u count) {
|
|||||||
/* calculate clamped intensity, taken from VGABIOS */
|
/* calculate clamped intensity, taken from VGABIOS */
|
||||||
Bit32u i=(( 77*red + 151*green + 28*blue ) + 0x80) >> 8;
|
Bit32u i=(( 77*red + 151*green + 28*blue ) + 0x80) >> 8;
|
||||||
Bit8u ic=(i>0x3f) ? 0x3f : ((Bit8u)(i & 0xff));
|
Bit8u ic=(i>0x3f) ? 0x3f : ((Bit8u)(i & 0xff));
|
||||||
INT10_SetSingleDacRegister(start_reg+ct,ic,ic,ic);
|
INT10_SetSingleDACRegister(start_reg+ct,ic,ic,ic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,6 +412,8 @@ Bitu XMS_Handler(void) {
|
|||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bitu GetEMSType(Section_prop * section);
|
||||||
|
|
||||||
class XMS: public Module_base {
|
class XMS: public Module_base {
|
||||||
private:
|
private:
|
||||||
CALLBACK_HandlerObject callbackhandler;
|
CALLBACK_HandlerObject callbackhandler;
|
||||||
@ -445,7 +447,8 @@ public:
|
|||||||
|
|
||||||
/* Set up UMB chain */
|
/* Set up UMB chain */
|
||||||
umb_available=section->Get_bool("umb");
|
umb_available=section->Get_bool("umb");
|
||||||
DOS_BuildUMBChain(section->Get_bool("umb"),section->Get_bool("ems"));
|
bool ems_available = GetEMSType(section)>0;
|
||||||
|
DOS_BuildUMBChain(section->Get_bool("umb"),ems_available);
|
||||||
}
|
}
|
||||||
|
|
||||||
~XMS(){
|
~XMS(){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user