This commit is contained in:
OBattler
2021-05-20 07:09:50 +02:00
19 changed files with 641 additions and 224 deletions

View File

@@ -1,55 +1,65 @@
86Box
=====
**86Box** is an IBM PC system emulator that specializes in running old
operating systems and software designed for IBM PC systems and compatibles
from 1981 through fairly recent system designs based on the PCI bus.
**86Box** is a low level x86 emulator that runs older operating systems and software designed for IBM PC systems and compatibles from 1981 through fairly recent system designs based on the PCI bus.
86Box is released under the GNU General Public License, version 2 only.
For more information, see the `COPYING` file.
The project maintainer is [OBattler](https://github.com/OBattler).
If you need a configuration manager for 86Box, use the [86Box Manager](https://github.com/86Box/86BoxManager), our
officially endorsed 86Box configuration manager, developed by Overdoze ([daviunic](https://github.com/daviunic)).
Community
---------
We operate an IRC channel and a Discord server for discussing anything related
to retro computing and, of course, 86Box. We look forward to hearing from you!
[![Visit our IRC channel](https://kiwiirc.com/buttons/irc.ringoflightning.net/softhistory.png)](https://kiwiirc.com/client/irc.ringoflightning.net/?nick=86box|?#softhistory)
[![Visit our Discord server](https://discordapp.com/api/guilds/262614059009048590/embed.png)](https://discord.gg/QXK9XTv)
Getting started
---------------
See [our documentation](https://86box.readthedocs.io/en/latest/index.html) for an overview of the emulator's features and user interface.
Building
Features
--------
See the [build guide](doc/build.md).
* Easy to use interface inspired by mainstream hypervisor software
* Low level emulation of 8086-based processors up to the Pentium with focus on accuracy
* Great range of customizability of virtual machines
* Many available systems, such as the very first IBM PC 5150 from 1981, or the more obscure IBM PS/2 line of systems based on the Micro Channel Architecture
* Lots of supported peripherals including video adapters, sound cards, network adapters, hard disk controllers, and SCSI adapters
* MIDI output to Windows built-in MIDI support, FluidSynth, or emulated Roland synthesizers
* Supports running MS-DOS, older Windows versions, OS/2, many Linux distributions, or vintage systems such as BeOS or NEXTSTEP, and applications for these systems
Automatic builds
--------------
For your convenience, we compile a number of 86Box builds per revision on our
Jenkins instance.
System requirements and recommendations
---------------------------------------
* Intel Core 2 or AMD Athlon 64 processor
* Windows 7 Service Pack 1, Windows 8.1 or Windows 10
* 4 GB of RAM
Performance may vary depending on both host and guest configuration. Most emulation logic is executed in a single thread, therefore generally systems with better IPC (instructions per clock) should be able to emulate higher clock speeds.
It is also recommended to use the [86Box Manager](https://github.com/86Box/86BoxManager) by [daviunic](https://github.com/daviunic) (Overdoze) to manage virtual machines. However, it is also possible to use 86Box on its own with the `--vmpath`/`-P` command line option.
Downloads
---------
The latest stable version of 86Box is version 2.07, which was released on November 20, 2019, and is available from our [GitHub repository](https://github.com/86Box/86Box/releases/tag/v2.07).
### Automatic builds
We also offer automatic builds, which are built from the latest source code and contain the latest bugfixes and improvements, but may not be as stable and/or optimized as stable builds.
| Regular | Debug | Experimental |
|:-------:|:-----:|:------------:|
|[![Build Status](http://ci.86box.net/job/86Box/badge/icon)](http://ci.86box.net/job/86Box)|[![Build Status](http://ci.86box.net/job/86Box-Debug/badge/icon)](http://ci.86box.net/job/86Box-Debug)|[![Build Status](http://ci.86box.net/job/86Box-Dev/badge/icon)](http://ci.86box.net/job/86Box-Dev)
### Legend
* **Regular** builds are compiled using the settings in the building guide
above. Use these if you don't know which build to use.
* **Debug** builds are same as regular builds but include debug symbols.
If you don't need them, you don't need to use this build.
* **Experimental (Dev)** builds are similar to regular builds but are compiled
with certain unfinished features enabled. These builds are not optimized for maximum performance.
#### Legend
* **Regular** builds are compiled using the settings in the building guide above. Use these if you don't know which build to use.
* **Debug** builds are same as regular builds but include debug symbols. If you don't need them, you don't need to use this build.
* **Experimental (Dev)** builds are compiled with certain unfinished features enabled. These builds are not optimized for maximum performance.
Getting started
---------------
See [our documentation](https://86box.readthedocs.io/en/latest/index.html) for an overview of the emulator's features and user interface.
Community
---------
We operate an IRC channel and a Discord server for discussing 86Box, its development and anything related to retro computing. We look forward to hearing from you!
[![Visit our IRC channel](https://kiwiirc.com/buttons/irc.ringoflightning.net/softhistory.png)](https://kiwiirc.com/client/irc.ringoflightning.net/?nick=86box|?#softhistory)
[![Visit our Discord server](https://discordapp.com/api/guilds/262614059009048590/embed.png)](https://discord.gg/QXK9XTv)
Licensing
---------
86Box is released under the [GNU General Public License, version 2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) only. For more information, see the `COPYING` file in the root of the repository.
The emulator can also optionally make use of [munt](https://github.com/munt/munt), [FluidSynth](https://www.fluidsynth.org/), [Ghostscript](https://www.ghostscript.com/) and [Discord Game SDK](https://discord.com/developers/docs/game-sdk/sdk-starter-guide), which are distributed under their respective licenses.
Donations
---------
We do not charge you for the emulator but donations are still welcome:
https://paypal.me/86Box.
You can now also support the project on Patreon:
You can also support the project on Patreon:
https://www.patreon.com/86box.

View File

@@ -1 +0,0 @@
This directory contains 86Box documentation.

View File

@@ -1,38 +0,0 @@
Building
========
In order to compile 86Box from this repository, please follow this step-by-step guide:
1. Install the [MSYS2](https://www.msys2.org/) environment. The rest of the guide will refer to the directory that you install it to (`C:\msys32` or `C:\msys64` by default) as the MSYS2 root.
2. Launch your MSYS2 environment using the `MSYS2 MinGW 32-bit` shortcut. If you do not want to use the shortcut, launch it using the `mingw32.exe` executable in the MSYS2 root.
3. Once launched, you should update the environment:
```console
$ pacman -Syu
```
You may need to do this twice, just follow the on-screen instructions. Make sure you re-run the command periodically to keep the environment up-to-date.
4. Run the following command to install all of the dependencies:
```console
$ pacman -S gdb make git mingw-w64-i686-toolchain mingw-w64-i686-openal mingw-w64-i686-freetype mingw-w64-i686-SDL2 mingw-w64-i686-zlib mingw-w64-i686-libpng
```
5. Once the environment is fully updated and all dependencies are installed, change directory to `src`:
```console
$ cd path/to/86Box/src
```
6. Start the actual compilation process:
```console
$ make -f win/Makefile.mingw
```
By default, `make` does not run in parallel. If you want it to use more threads, use the `-j` switch with the number of threads, e.g. `-j4`. However, keep in mind that you should not exceed your thread (logical processor) count, since that just uses more resources for little to no gain.
7. If the compilation succeeded (which it almost always should), you will find `86Box.exe` in the `src` directory.
8. In order to test your fresh build, replace the `86Box.exe` in your current 86Box environment with your freshly built one. If you do not have a pre-existing 86Box environment, download the latest successful build from https://ci.86box.net, and the latest ROM set from https://github.com/86Box/roms.
9. Enjoy using and testing the emulator! :)
If you encounter issues at any step or have additional questions, please join
the IRC channel or the appropriate channel on our Discord server and wait patiently for someone to help you.

View File

@@ -845,18 +845,22 @@ pc_reset_hard_init(void)
cycles = cycles_main = 0;
mbstowcs(wmachine, machine_getname(), strlen(machine_getname())+1);
mbstowcs(wcpufamily, cpu_f->name,
strlen(cpu_f->name)+1);
wcp = wcschr(wcpufamily, L'(');
if (wcp) /* remove parentheses */
*(wcp - 1) = L'\0';
mbstowcs(wcpu, cpu_s->name, strlen(cpu_s->name)+1);
swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls",
EMU_NAME_W, EMU_VERSION_W, wmachine, wcpufamily, wcpu,
plat_get_string(IDS_2077));
swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls",
EMU_NAME_W, EMU_VERSION_W, wmachine, wcpufamily, wcpu,
(mouse_get_buttons() > 2) ? plat_get_string(IDS_2078) : plat_get_string(IDS_2079));
if (!cpu_override)
mbstowcs(wcpufamily, cpu_f->name, strlen(cpu_f->name)+1);
else
swprintf(wcpufamily, sizeof_w(wcpufamily), L"[U] %hs", cpu_f->name);
wcp = wcschr(wcpufamily, L'(');
if (wcp) /* remove parentheses */
*(wcp - 1) = L'\0';
mbstowcs(wcpu, cpu_s->name, strlen(cpu_s->name)+1);
swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls",
EMU_NAME_W, EMU_VERSION_W, wmachine, wcpufamily, wcpu,
plat_get_string(IDS_2077));
swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls",
EMU_NAME_W, EMU_VERSION_W, wmachine, wcpufamily, wcpu,
(mouse_get_buttons() > 2) ? plat_get_string(IDS_2078) : plat_get_string(IDS_2079));
}

View File

@@ -138,7 +138,7 @@ et6000_init(const device_t *info)
device_add(&port_92_device);
/* Defaults */
dev->regs[0x13] = 1;
dev->regs[3] = 1;
/* Shadow Programming */
et6000_shadow_control(0xf0000, 0x10000, 0, 1);

View File

@@ -118,6 +118,9 @@
#define IDS_2142 2142 // "Monitor in sleep mode"
#define IDS_2143 2143 // "OpenGL Shaders (*.GLSL)..."
#define IDS_2144 2144 // "OpenGL options"
#define IDS_2145 2145 // "You are loading an unsupported..."
#define IDS_2146 2146 // "CPU type filtering based on..."
#define IDS_2147 2147 // "Continue"
#define IDS_4096 4096 // "Hard disk (%s)"
#define IDS_4097 4097 // "%01i:%01i"
@@ -225,7 +228,7 @@
#define IDS_LANG_ENUS IDS_7168
#define STR_NUM_2048 97
#define STR_NUM_2048 100
#define STR_NUM_3072 11
#define STR_NUM_4096 39
#define STR_NUM_4352 6

View File

@@ -208,8 +208,8 @@ extern void ati68860_ramdac_set_render(void *p, svga_t *svga);
extern void ati68860_ramdac_set_pallook(void *p, int i, uint32_t col);
extern void ati68860_hwcursor_draw(svga_t *svga, int displine);
extern void att49x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga);
extern uint8_t att49x_ramdac_in(uint16_t addr, void *p, svga_t *svga);
extern void att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga);
extern uint8_t att49x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga);
extern float av9194_getclock(int clock, void *p);
@@ -236,8 +236,8 @@ extern void ics2595_write(void *p, int strobe, int dat);
extern double ics2595_getclock(void *p);
extern void ics2595_setclock(void *p, double clock);
extern void sc1148x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga);
extern uint8_t sc1148x_ramdac_in(uint16_t addr, void *p, svga_t *svga);
extern void sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga);
extern uint8_t sc1148x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga);
extern void sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga);
extern uint8_t sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga);
@@ -257,6 +257,7 @@ extern uint8_t tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga);
#ifdef EMU_DEVICE_H
extern const device_t ati68860_ramdac_device;
extern const device_t att490_ramdac_device;
extern const device_t att491_ramdac_device;
extern const device_t att492_ramdac_device;
extern const device_t av9194_device;
extern const device_t bt484_ramdac_device;
@@ -272,6 +273,7 @@ extern const device_t icd2061_device;
extern const device_t ics9161_device;
extern const device_t sc11483_ramdac_device;
extern const device_t sc11487_ramdac_device;
extern const device_t sc11484_ramdac_device;
extern const device_t sc1502x_ramdac_device;
extern const device_t sdac_ramdac_device;
extern const device_t stg_ramdac_device;

View File

@@ -316,6 +316,9 @@ extern const device_t paradise_wd90c11_megapc_device;
extern const device_t paradise_wd90c11_device;
extern const device_t paradise_wd90c30_device;
/* Realtek (S)VGA */
extern const device_t realtek_rtg3106_device;
/* S3 9XX/8XX/Vision/Trio */
extern const device_t s3_orchid_86c911_isa_device;
extern const device_t s3_diamond_stealth_vram_isa_device;

View File

@@ -21,7 +21,7 @@ add_library(vid OBJECT video.c vid_table.c vid_cga.c vid_cga_comp.c
vid_ati28800.c vid_ati_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c
vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c
vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c vid_et4000w32.c
vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c
vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c vid_rtg310x.c
vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c
vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c
vid_sdac_ramdac.c vid_voodoo.c vid_voodoo_banshee.c

View File

@@ -39,88 +39,114 @@ typedef struct
enum
{
ATT_490_1 = 0,
ATT_492_3
ATT_490 = 0,
ATT_491,
ATT_492
};
static void
att49x_ramdac_control(uint8_t val, void *p, svga_t *svga)
{
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p;
ramdac->ctrl = val;
switch (ramdac->ctrl >> 4) {
case 0:
case 1:
case 2:
case 3:
svga->bpp = 8;
break;
case 4:
case 5:
svga->bpp = 15;
break;
case 6:
case 0xc:
svga->bpp = 16;
break;
case 7:
case 0xe:
svga->bpp = 24;
break;
}
if (ramdac->type == ATT_490 || ramdac->type == ATT_491)
svga_set_ramdac_type(svga, (val & 2) ? RAMDAC_8BIT : RAMDAC_6BIT);
svga_recalctimings(svga);
}
void
att49x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
{
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p;
uint8_t rs = (addr & 0x03);
rs |= ((!!rs2) << 2);
switch (addr) {
case 0x3C6:
if (ramdac->state == 4) {
ramdac->state = 0;
ramdac->ctrl = val;
if (ramdac->type == ATT_490_1)
svga_set_ramdac_type(svga, (val & 2) ? RAMDAC_8BIT : RAMDAC_6BIT);
switch (val)
{
case 0:
svga->bpp = 8;
break;
case 0x20:
svga->bpp = 15;
break;
case 0x40:
svga->bpp = 24;
break;
case 0x60:
svga->bpp = 16;
break;
case 0x80:
case 0xa0:
svga->bpp = 15;
break;
case 0xc0:
svga->bpp = 16;
break;
case 0xe0:
svga->bpp = 24;
break;
}
svga_recalctimings(svga);
return;
}
switch (rs) {
case 0x00:
case 0x01:
case 0x03:
case 0x04:
case 0x05:
case 0x07:
svga_out(addr, val, svga);
ramdac->state = 0;
break;
case 0x3C7:
case 0x3C8:
case 0x3C9:
case 0x02:
switch (ramdac->state) {
case 4:
att49x_ramdac_control(val, ramdac, svga);
break;
default:
svga_out(addr, val, svga);
break;
}
break;
case 0x06:
att49x_ramdac_control(val, ramdac, svga);
ramdac->state = 0;
break;
}
svga_out(addr, val, svga);
}
uint8_t
att49x_ramdac_in(uint16_t addr, void *p, svga_t *svga)
att49x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
{
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p;
uint8_t temp = svga_in(addr, svga);
uint8_t temp = 0xff;
uint8_t rs = (addr & 0x03);
rs |= ((!!rs2) << 2);
switch (addr) {
case 0x3C6:
if (ramdac->state == 4) {
ramdac->state = 0;
temp = ramdac->ctrl;
break;
}
ramdac->state++;
switch (rs) {
case 0x00:
case 0x01:
case 0x03:
case 0x04:
case 0x05:
case 0x07:
temp = svga_in(addr, svga);
ramdac->state = 0;
break;
case 0x3C7:
case 0x3C8:
case 0x3C9:
case 0x02:
switch (ramdac->state) {
case 1:
case 2: case 3:
temp = 0x00;
ramdac->state++;
break;
case 4:
temp = ramdac->ctrl;
ramdac->state = 0;
break;
default:
temp = svga_in(addr, svga);
ramdac->state++;
break;
}
break;
case 0x06:
temp = ramdac->ctrl;
ramdac->state = 0;
break;
}
@@ -153,16 +179,24 @@ att49x_ramdac_close(void *priv)
const device_t att490_ramdac_device =
{
"AT&T 20c490/20c491 RAMDAC",
0, ATT_490_1,
"AT&T 20c490 RAMDAC",
0, ATT_490,
att49x_ramdac_init, att49x_ramdac_close,
NULL, { NULL }, NULL, NULL
};
const device_t att491_ramdac_device =
{
"AT&T 20c491 RAMDAC",
0, ATT_491,
att49x_ramdac_init, att49x_ramdac_close,
NULL, { NULL }, NULL, NULL
};
const device_t att492_ramdac_device =
{
"AT&T 20c492/20c493 RAMDAC",
0, ATT_492_3,
"AT&T 20c492 RAMDAC",
0, ATT_492,
att49x_ramdac_init, att49x_ramdac_close,
NULL, { NULL }, NULL, NULL
};

View File

@@ -59,7 +59,7 @@ typedef struct ht216_t
uint8_t bg_plane_sel, fg_plane_sel;
uint8_t ht_regs[256];
uint8_t pos102, extensions;
uint8_t extensions;
uint8_t pos_regs[8];
} ht216_t;
@@ -131,7 +131,7 @@ ht216_log(const char *fmt, ...)
static void
ht216_recalc_bank_regs(ht216_t *ht216, int mode)
{
if (mode) {
if (mode) {
ht216->read_bank_reg[0] = ht216->ht_regs[0xe8];
ht216->write_bank_reg[0] = ht216->ht_regs[0xe8];
ht216->read_bank_reg[1] = ht216->ht_regs[0xe9];
@@ -176,7 +176,7 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
ht216->clk_sel = (ht216->clk_sel & ~3) | ((val & 0x0c) >> 2);
/*Bit 17 of the display memory address, only active on odd/even modes, has no effect on graphics modes.*/
ht216->misc = val;
ht216_log("HT216 misc val = %02x\n", val);
ht216_log("HT216 misc val = %02x, mode = 0, chain4 = %x\n", val, svga->chain4);
ht216_recalc_bank_regs(ht216, 0);
ht216_remap(ht216);
svga->fullchange = changeframecount;
@@ -305,6 +305,7 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
case 0xe0:
/*Bank registers*/
case 0xe8: case 0xe9:
ht216_log("HT216 reg 0x%02x write = %02x, mode = 1, chain4 = %x\n", svga->seqaddr & 0xff, val, svga->chain4);
ht216_recalc_bank_regs(ht216, 1);
ht216_remap(ht216);
break;
@@ -339,7 +340,7 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
case 0xf6:
/*Bits 18 and 19 of the display memory address*/
ht216_log("HT216 reg 0xf6 write = %02x, vram mask = %08x, cr17 = %02x\n", val & 0x40, svga->vram_display_mask, svga->crtc[0x17]);
ht216_log("HT216 reg 0xf6 write = %02x, mode = 0, chain4 = %x, vram mask = %08x, cr17 = %02x\n", val, svga->chain4, svga->vram_display_mask, svga->crtc[0x17]);
ht216_recalc_bank_regs(ht216, 0);
ht216_remap(ht216);
svga->fullchange = changeframecount;
@@ -348,12 +349,13 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
case 0xf9:
/*Bit 16 of the display memory address, only active when in chain4 mode and 256 color mode.*/
ht216_log("HT216 reg 0xf9 write = %02x\n", val & HT_REG_F9_XPSEL);
ht216_log("HT216 reg 0xf9 write = %02x, mode = 0, chain4 = %x\n", val & HT_REG_F9_XPSEL, svga->chain4);
ht216_recalc_bank_regs(ht216, 0);
ht216_remap(ht216);
break;
case 0xfc:
ht216_log("HT216 reg 0xfc write = %02x, mode = 0, chain4 = %x\n", val, svga->chain4);
ht216_recalc_bank_regs(ht216, 0);
ht216_remap(ht216);
svga->fullchange = changeframecount;
@@ -366,13 +368,16 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9:
if (ht216->id == 0x7152)
sc1148x_ramdac_out(addr, val, svga->ramdac, svga);
sc1148x_ramdac_out(addr, 1, val, svga->ramdac, svga);
else
svga_out(addr, val, svga);
return;
case 0x3cf:
if (svga->gdcaddr == 5) {
if (svga->gdcaddr == 4) {
svga->readplane = val & 3;
ht216_remap(ht216);
} else if (svga->gdcaddr == 5) {
svga->chain2_read = val & 0x10;
ht216_remap(ht216);
} else if (svga->gdcaddr == 6) {
@@ -404,21 +409,21 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
break;
case 0x46e8:
if (ht216->id == 0x7152 && ht216->isabus) {
io_removehandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
}
io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
mem_mapping_disable(&svga->mapping);
mem_mapping_disable(&ht216->linear_mapping);
if (val & 8) {
if (ht216->id == 0x7152 && ht216->isabus) {
io_sethandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
}
io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
mem_mapping_enable(&svga->mapping);
ht216_remap(ht216);
}
break;
case 0x102:
if (ht216->id == 0x7152 && ht216->isabus) {
ht216->pos102 = val;
}
break;
}
svga_out(addr, val, svga);
@@ -436,11 +441,6 @@ ht216_in(uint16_t addr, void *p)
addr ^= 0x60;
switch (addr) {
case 0x102:
if (ht216->id == 0x7152 && ht216->isabus)
return ht216->pos102;
break;
case 0x105:
if (ht216->id == 0x7152 && ht216->isabus)
return ht216->extensions;
@@ -503,7 +503,7 @@ ht216_in(uint16_t addr, void *p)
case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9:
if (ht216->id == 0x7152)
return sc1148x_ramdac_in(addr, svga->ramdac, svga);
return sc1148x_ramdac_in(addr, 1, svga->ramdac, svga);
return svga_in(addr, svga);
case 0x3cc:
@@ -514,6 +514,15 @@ ht216_in(uint16_t addr, void *p)
case 0x3D5:
if (svga->crtcreg == 0x1f)
return svga->crtc[0xc] ^ 0xea;
if (svga->crtcreg == 0x22)
return svga->latch.b[svga->readplane];
if (svga->crtcreg == 0x24) {
if (svga->attrff)
return svga->attraddr | 0x80;
else
return svga->attraddr;
break;
}
return svga->crtc[svga->crtcreg];
}
@@ -529,6 +538,7 @@ ht216_remap(ht216_t *ht216)
mem_mapping_disable(&ht216->linear_mapping);
if (ht216->ht_regs[0xc8] & HT_REG_C8_XLAM) {
/*Linear mapping enabled*/
ht216_log("Linear mapping enabled\n");
ht216->linear_base = ((ht216->ht_regs[0xc9] & 0xf) << 20) | (ht216->ht_regs[0xcf] << 24);
mem_mapping_disable(&svga->mapping);
mem_mapping_set_addr(&ht216->linear_mapping, ht216->linear_base, 0x100000);
@@ -556,7 +566,7 @@ ht216_remap(ht216_t *ht216)
}
#ifdef ENABLE_HT216_LOG
ht216_log("Rgisters: %02X, %02X, %02X, %02X, %02X\n", ht216->misc, ht216->ht_regs[0xe8], ht216->ht_regs[0xe9],
ht216_log("Registers: %02X, %02X, %02X, %02X, %02X\n", ht216->misc, ht216->ht_regs[0xe8], ht216->ht_regs[0xe9],
ht216->ht_regs[0xf6], ht216->ht_regs[0xf9]);
ht216_log("Banks: %08X, %08X, %08X, %08X\n", ht216->read_banks[0], ht216->read_banks[1],
ht216->write_banks[0], ht216->write_banks[1]);
@@ -652,7 +662,7 @@ ht216_recalctimings(svga_t *svga)
case 10: svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; break;
}
if ((ht216->ht_regs[0xfc] & 8) && (ht216->id == 0x7152))
if (ht216->id == 0x7152)
svga->clock *= 2;
svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12);
@@ -689,8 +699,14 @@ ht216_recalctimings(svga_t *svga)
svga->render = svga_render_8bpp_lowres;
}
} else if (ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE) {
if (ht216->id == 0x7152)
if (ht216->id == 0x7152) {
svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5);
if (!(svga->crtc[1] & 1))
svga->hdisp--;
svga->hdisp++;
svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8;
svga->rowoffset <<= 1;
}
svga->render = svga_render_8bpp_highres;
}
} else if (svga->bpp == 15) {
@@ -1424,11 +1440,6 @@ void
memset(ht216, 0, sizeof(ht216_t));
svga = &ht216->svga;
if ((info->flags & DEVICE_ISA) && (info->local == 0x7152)) {
io_sethandler(0x0102, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
io_sethandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
}
io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
io_sethandler(0x46e8, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
@@ -1494,7 +1505,7 @@ void
svga->decode_mask = mem_size - 1;
if (has_rom == 4)
svga->ramdac = device_add(&sc11483_ramdac_device);
svga->ramdac = device_add(&sc11484_ramdac_device);
if ((info->flags & DEVICE_VLB) || (info->flags & DEVICE_MCA)) {
mem_mapping_set_handler(&svga->mapping, ht216_read, NULL, NULL, ht216_write, ht216_writew, ht216_writel);

357
src/video/vid_rtg310x.c Normal file
View File

@@ -0,0 +1,357 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the Realtek RTG series of VGA ISA chips.
*
*
*
* Authors: TheCollector1995, <mariogplayer90@gmail.com>
*
* Copyright 2021 TheCollector1995.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <86box/vid_svga_render.h>
#define BIOS_ROM_PATH "roms/video/rtg/realtekrtg3106.BIN"
typedef struct {
const char *name;
int type;
svga_t svga;
rom_t bios_rom;
uint8_t bank3d6,
bank3d7;
uint32_t vram_size,
vram_mask;
} rtg_t;
static video_timings_t timing_rtg_isa = {VIDEO_ISA, 3, 3, 6, 5, 5, 10};
static void rtg_recalcbanking(rtg_t *dev)
{
svga_t *svga = &dev->svga;
svga->write_bank = (dev->bank3d7 & 0x0f) * 65536;
if (svga->gdcreg[0x0f] & 4)
svga->read_bank = (dev->bank3d6 & 0x0f) * 65536;
else
svga->read_bank = svga->write_bank;
}
static uint8_t
rtg_in(uint16_t addr, void *priv)
{
rtg_t *dev = (rtg_t *)priv;
svga_t *svga = &dev->svga;
uint8_t ret = 0;
if (((addr & 0xfff0) == 0x3d0 ||
(addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60;
switch (addr) {
case 0x3ce:
return svga->gdcaddr;
case 0x3cf:
if (svga->gdcaddr == 0x0c)
return svga->gdcreg[0x0c] | 4;
else if ((svga->gdcaddr > 8) && (svga->gdcaddr != 0x0c))
return svga->gdcreg[svga->gdcaddr];
break;
case 0x3d4:
return svga->crtcreg;
case 0x3d5:
if (!(svga->crtc[0x1e] & 0x80) && (svga->crtcreg > 0x18))
return 0xff;
if (svga->crtcreg == 0x1a)
return dev->type << 6;
if (svga->crtcreg == 0x1e) {
if (dev->vram_size == 1024)
ret = 2;
else if (dev->vram_size == 512)
ret = 1;
else
ret = 0;
return svga->crtc[0x1e] | ret;
}
return svga->crtc[svga->crtcreg];
case 0x3d6:
return dev->bank3d6;
case 0x3d7:
return dev->bank3d7;
}
return svga_in(addr, svga);
}
static void
rtg_out(uint16_t addr, uint8_t val, void *priv)
{
rtg_t *dev = (rtg_t *)priv;
svga_t *svga = &dev->svga;
uint8_t old;
if (((addr & 0xfff0) == 0x3d0 ||
(addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60;
switch (addr) {
case 0x3ce:
svga->gdcaddr = val;
return;
case 0x3cf:
if (svga->gdcaddr > 8) {
svga->gdcreg[svga->gdcaddr] = val;
switch (svga->gdcaddr) {
case 0x0b:
case 0x0c:
svga->fullchange = changeframecount;
svga_recalctimings(svga);
break;
case 0x0f:
rtg_recalcbanking(dev);
return;
}
}
break;
case 0x3d4:
svga->crtcreg = val & 0x3f;
return;
case 0x3d5:
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
return;
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
if (svga->crtc[0x1e] & 0x80) {
switch (svga->crtcreg) {
case 0x19:
svga->vram_display_mask = (val & 0x20) ? dev->vram_mask : 0x3ffff;
svga->fullchange = changeframecount;
svga_recalctimings(svga);
break;
}
}
if (old != val) {
if (svga->crtcreg < 0x0e || svga->crtcreg > 0x10) {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
break;
case 0x3d6:
dev->bank3d6 = val;
rtg_recalcbanking(dev);
return;
case 0x3d7:
dev->bank3d7 = val;
rtg_recalcbanking(dev);
return;
}
svga_out(addr, val, svga);
}
static void
rtg_recalctimings(svga_t *svga)
{
svga->ma_latch = ((svga->crtc[0x19] & 0x10) << 16) | ((svga->crtc[0x19] & 0x40) << 17);
svga->interlace = (svga->crtc[0x19] & 1);
/*Clock table not available, currently a guesswork*/
switch (((svga->miscout >> 2) & 3) | ((svga->gdcreg[0x0c] & 0x20) >> 3)) {
case 0:
case 1:
break;
case 2:
svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0;
break;
case 3:
svga->clock = (cpuclock * (double)(1ull << 32)) / 65100000.0;
break;
case 4:
svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0;
break;
case 5:
svga->clock = (cpuclock * (double)(1ull << 32)) / 50000000.0;
break;
case 6:
svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0;
break;
case 7:
svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0;
break;
}
switch (svga->gdcreg[0x0c] & 3) {
case 1:
svga->clock /= 1.5;
break;
case 2:
svga->clock /= 2;
break;
case 3:
svga->clock /= 4;
break;
}
if (svga->bpp == 8) {
if (svga->crtc[0x19] & 2) {
svga->render = svga_render_8bpp_highres;
svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5);
svga->hdisp++;
svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8;
if (svga->hdisp == 1280) {
svga->hdisp >>= 1;
} else
svga->rowoffset <<= 1;
}
}
}
static void *
rtg_init(const device_t *info)
{
const char *fn;
rtg_t *dev;
dev = (rtg_t *)malloc(sizeof(rtg_t));
memset(dev, 0x00, sizeof(rtg_t));
dev->name = info->name;
dev->type = info->local;
fn = BIOS_ROM_PATH;
switch(dev->type) {
case 2: /* ISA RTG3106 */
dev->vram_size = device_get_config_int("memory") << 10;
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_rtg_isa);
svga_init(info, &dev->svga, dev, dev->vram_size,
rtg_recalctimings, rtg_in, rtg_out,
NULL, NULL);
io_sethandler(0x03c0, 32,
rtg_in,NULL,NULL, rtg_out,NULL,NULL, dev);
break;
}
dev->svga.bpp = 8;
dev->svga.miscout = 1;
dev->vram_mask = dev->vram_size - 1;
rom_init(&dev->bios_rom, (char *) fn,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
return(dev);
}
static void
rtg_close(void *priv)
{
rtg_t *dev = (rtg_t *)priv;
svga_close(&dev->svga);
free(dev);
}
static void
rtg_speed_changed(void *priv)
{
rtg_t *dev = (rtg_t *)priv;
svga_recalctimings(&dev->svga);
}
static void
rtg_force_redraw(void *priv)
{
rtg_t *dev = (rtg_t *)priv;
dev->svga.fullchange = changeframecount;
}
static int
rtg_available(void)
{
return rom_present(BIOS_ROM_PATH);
}
static const device_config_t rtg_config[] =
{
{
"memory", "Memory size", CONFIG_SELECTION, "", 1024, "", { 0 },
{
{
"256 KB", 256
},
{
"512 KB", 512
},
{
"1 MB", 1024
},
{
""
}
}
},
{
"", "", -1
}
};
const device_t realtek_rtg3106_device = {
"Realtek RTG3106 (ISA)",
DEVICE_ISA | DEVICE_AT,
2,
rtg_init, rtg_close, NULL,
{ rtg_available },
rtg_speed_changed,
rtg_force_redraw,
rtg_config
};

View File

@@ -2209,9 +2209,9 @@ s3_out(uint16_t addr, uint8_t val, void *p)
} else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || s3->chip == S3_VISION968)
ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga);
else if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805))
att49x_ramdac_out(addr, val, svga->ramdac, svga);
att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga);
else if (s3->chip < S3_86C928)
sc1148x_ramdac_out(addr, val, svga->ramdac, svga);
sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga);
else
sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga);
return;
@@ -2463,9 +2463,9 @@ s3_in(uint16_t addr, void *p)
} else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || s3->chip == S3_VISION968)
return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga);
else if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805))
return att49x_ramdac_in(addr, svga->ramdac, svga);
return att49x_ramdac_in(addr, rs2, svga->ramdac, svga);
else if (s3->chip <= S3_86C924)
return sc1148x_ramdac_in(addr, svga->ramdac, svga);
return sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga);
else
return sdac_ramdac_in(addr, rs2, svga->ramdac, svga);
break;
@@ -5938,7 +5938,7 @@ static void *s3_init(const device_t *info)
s3->packed_mmio = 0;
svga->crtc[0x5a] = 0x0a;
svga->ramdac = device_add(&att490_ramdac_device);
svga->ramdac = device_add(&att491_ramdac_device);
svga->clock_gen = device_add(&av9194_device);
svga->getclock = av9194_getclock;
break;

View File

@@ -38,12 +38,24 @@ typedef struct
void
sc1148x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
{
sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p;
uint8_t rs = (addr & 0x03);
rs |= ((!!rs2) << 2);
switch (addr) {
case 0x3C6:
switch (rs) {
case 0x00:
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x07:
svga_out(addr, val, svga);
ramdac->state = 0;
break;
case 0x06:
if (ramdac->state == 4) {
ramdac->state = 0;
ramdac->ctrl = val;
@@ -60,45 +72,42 @@ sc1148x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
}
ramdac->state = 0;
break;
case 0x3C7:
case 0x3C8:
case 0x3C9:
ramdac->state = 0;
break;
}
svga_out(addr, val, svga);
}
uint8_t
sc1148x_ramdac_in(uint16_t addr, void *p, svga_t *svga)
sc1148x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
{
sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p;
uint8_t temp = svga_in(addr, svga);
uint8_t temp = 0xff;
uint8_t rs = (addr & 0x03);
rs |= ((!!rs2) << 2);
switch (addr) {
case 0x3C6:
switch (rs) {
case 0x00:
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x07:
temp = svga_in(addr, svga);
ramdac->state = 0;
break;
case 0x06:
if (ramdac->state == 4) {
ramdac->state = 0;
temp = ramdac->ctrl;
if (ramdac->type == 1) {
if (ramdac->ctrl & 0x80)
if (((ramdac->ctrl >> 4) == 1) || ((ramdac->ctrl >> 4) == 3))
temp |= 1;
else
temp &= ~1;
}
break;
}
ramdac->state++;
break;
case 0x3C7:
case 0x3C8:
case 0x3C9:
ramdac->state = 0;
break;
}
return temp;
@@ -141,3 +150,11 @@ const device_t sc11487_ramdac_device =
sc1148x_ramdac_init, sc1148x_ramdac_close,
NULL, { NULL }, NULL, NULL
};
const device_t sc11484_ramdac_device =
{
"Sierra SC11484 RAMDAC",
0, 2,
sc1148x_ramdac_init, sc1148x_ramdac_close,
NULL, { NULL }, NULL, NULL
};

View File

@@ -103,6 +103,7 @@ video_cards[] = {
{ "plantronics", &colorplus_device },
{ "pgc", &pgc_device },
{ "radius_isa", &radius_svga_multiview_isa_device },
{ "rtg3106", &realtek_rtg3106_device },
{ "sigma400", &sigma_device },
{ "px_s3_v7_801_isa", &s3_v7mirage_86c801_isa_device },
{ "tvga8900b", &tvga8900b_device },

View File

@@ -1104,6 +1104,9 @@ BEGIN
IDS_2142 "Monitor in sleep mode"
IDS_2143 "OpenGL Shaders (*.GLSL)\0*.GLSL\0All files (*.*)\0*.*\0"
IDS_2144 "OpenGL options"
IDS_2145 "You are loading an unsupported configuration"
IDS_2146 "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid."
IDS_2147 "Continue"
END
STRINGTABLE DISCARDABLE

View File

@@ -760,6 +760,7 @@ VIDOBJ := video.o \
vid_ht216.o \
vid_oak_oti.o \
vid_paradise.o \
vid_rtg310x.o \
vid_ti_cf62011.o \
vid_tvga.o \
vid_tgui9440.o vid_tkd8001_ramdac.o \

View File

@@ -625,15 +625,18 @@ static void opengl_main(void* param)
SetEvent(sync_objects.resize);
}
/* Clip to height. y2 can be out-of-bounds. */
int sub_height = MIN(info->y2, info->h) - info->y1;
if (!GLAD_GL_ARB_buffer_storage)
{
/* Fallback method, copy data to pixel buffer. */
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * read_pos, info->w * (info->y2 - info->y1) * sizeof(uint32_t), info->buffer);
glBufferSubData(GL_PIXEL_UNPACK_BUFFER, BUFFERBYTES * read_pos, info->w * sub_height * sizeof(uint32_t), info->buffer);
}
/* Update texture from pixel buffer. */
glPixelStorei(GL_UNPACK_SKIP_PIXELS, BUFFERPIXELS * read_pos);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, info->y1, info->w, info->y2 - info->y1, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, info->y1, info->w, sub_height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
/* Add fence to track when above gl commands are complete. */
info->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);

View File

@@ -1433,6 +1433,13 @@ ui_init(int nCmdShow)
/* Make the window visible on the screen. */
ShowWindow(hwnd, nCmdShow);
/* Warn the user about unsupported configs. */
if (cpu_override && ui_msgbox_ex(MBX_WARNING | MBX_QUESTION_OK, (void*)IDS_2145, (void*)IDS_2146, (void*)IDS_2147, (void*)IDS_2119, NULL))
{
DestroyWindow(hwnd);
return(0);
}
GetClipCursor(&oldclip);
/* Initialize the RawInput (keyboard) module. */