Merge branch 'master' of https://github.com/86Box/86Box.git into EngiNerd

This commit is contained in:
EngiNerd89
2021-02-07 00:24:21 +01:00
28 changed files with 1176 additions and 851 deletions

View File

@@ -5,17 +5,19 @@ on:
push:
paths:
- src/**
- "**/CMakeLists.txt"
- .github/workflows/**
- vcpkg.json
pull_request:
paths:
- src/**
- "**/CMakeLists.txt"
- .github/workflows/**
- vcpkg.json
env:
BUILD_TYPE: Release
BUILD_TYPE: RelWithDebInfo
jobs:
mingw:
@@ -56,30 +58,39 @@ jobs:
run: >-
cmake -S . -B build
-G "MSYS Makefiles"
-D CMAKE_BUILD_TYPE=$BUILD_TYPE
-D CMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}
-D DEV_BRANCH=${{ matrix.dev-build }}
-D NEW_DYNAREC=${{ matrix.new-dynarec }}
-D VNC=OFF
- name: Build
run: cmake --build build --config $BUILD_TYPE
run: cmake --build build
clang:
name: VS2019 ${{ matrix.toolset }} ${{ matrix.target-arch }} build (DEV_BUILD=${{ matrix.dev-build }}, NEW_DYNAREC=${{ matrix.new-dynarec }})
vs2019:
name: VS2019 ${{ matrix.build.name }} ${{ matrix.target-arch }} build (${{ matrix.toolset }})
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
dev-build: ['ON', 'OFF']
new-dynarec: ['ON', 'OFF']
build:
- name: Regular
dev-build: off
new-dynarec: off
type: Debug
- name: Dev
dev-build: on
new-dynarec: on
type: Debug
target-arch: ['Win32', 'x64', 'ARM', 'ARM64']
toolset: ['clangcl', 'v141']
toolset: ['clangcl', 'v142']
exclude:
- target-arch: 'ARM'
new-dynarec: 'OFF'
build:
new-dynarec: off
- target-arch: 'ARM64'
new-dynarec: 'OFF'
build:
new-dynarec: off
- target-arch: 'ARM'
toolset: 'clangcl'
@@ -94,9 +105,13 @@ jobs:
cmake -S . -B build
-G "Visual Studio 16 2019" -A ${{ matrix.target-arch }} -T ${{ matrix.toolset }}
-D CMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake
-D CMAKE_BUILD_TYPE=$BUILD_TYPE
-D DEV_BRANCH=${{ matrix.dev-build }}
-D NEW_DYNAREC=${{ matrix.new-dynarec }}
-D CMAKE_INSTALL_PREFIX=${{ github.workspace }}/build/artifacts
-D DEV_BRANCH=${{ matrix.build.dev-build }}
-D NEW_DYNAREC=${{ matrix.build.new-dynarec }}
-D VNC=OFF
- name: Build
run: cmake --build build --config $BUILD_TYPE
run: cmake --build build --config ${{ matrix.build.type }} --target install
- uses: actions/upload-artifact@v2
with:
name: '86Box-VS2019-${{ matrix.build.name }}-${{ matrix.target-arch }}-${{ matrix.toolset }}-${{ github.sha }}'
path: build/artifacts/bin/**

View File

@@ -15,8 +15,11 @@
cmake_minimum_required(VERSION 3.16)
cmake_policy(SET CMP0091 NEW)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
project(86Box
VERSION 2.10
VERSION 3.0
DESCRIPTION "Emulator of x86-based systems"
HOMEPAGE_URL "https://86box.github.io/"
LANGUAGES C CXX)
@@ -25,6 +28,8 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(TargetArch)
target_architecture(CMAKE_TARGET_ARCHITECTURES)
include(CPack)
include(CMakeDependentOption)
add_compile_definitions(CMAKE)
@@ -65,4 +70,16 @@ CMAKE_DEPENDENT_OPTION(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH"
CMAKE_DEPENDENT_OPTION(VECT486VL "HP Vectra 486VL" ON "DEV_BRANCH" OFF)
CMAKE_DEPENDENT_OPTION(DELLS4 "Dell Dimension XPS P60; Dell OptiPlex 560/L" ON "DEV_BRANCH" OFF)
# HACK: Avoid a MSVC2019 compiler bug on ARM64 Debug builds
if(MSVC_TOOLSET_VERSION GREATER_EQUAL 142 AND CMAKE_TARGET_ARCHITECTURES STREQUAL "armv8")
# Define a cache option in case somebody wants to disable this workaround
set(AVOID_LNK1322 ON CACHE BOOL "Prevent LNK1322 on MSVC2019 ARM64 debug builds")
if(AVOID_LNK1322)
message(STATUS "Working around LNK1322 (#1268)")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Gy")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Gy")
endif()
endif()
add_subdirectory(src)

View File

@@ -94,6 +94,11 @@ else()
add_subdirectory(codegen)
endif()
install(TARGETS 86Box)
if(VCPKG_TOOLCHAIN)
x_vcpkg_install_local_dependencies(TARGETS 86Box DESTINATION "bin")
endif()
add_subdirectory(device)
add_subdirectory(disk)
add_subdirectory(floppy)

View File

@@ -29,11 +29,13 @@
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/apm.h>
#include <86box/mem.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/port_92.h>
#include <86box/smram.h>
#include <86box/chipset.h>
#define disabled_shadow (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
@@ -45,122 +47,108 @@ ali1429_log(const char *fmt, ...)
{
va_list ap;
if (ali1429_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
if (ali1429_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define ali1429_log(fmt, ...)
#endif
typedef struct
{
uint8_t index, cfg_locked,
regs[256];
uint8_t index, cfg_locked,
regs[256];
smram_t *smram;
} ali1429_t;
static void ali1429_shadow_recalc(ali1429_t *dev)
{
uint32_t base, i, can_write, can_read;
uint32_t base, i, can_write, can_read;
shadowbios = (dev->regs[0x13] & 0x40) && (dev->regs[0x14] & 0x01);
shadowbios_write = (dev->regs[0x13] & 0x40) && (dev->regs[0x14] & 0x02);
shadowbios = (dev->regs[0x13] & 0x40) && (dev->regs[0x14] & 0x01);
shadowbios_write = (dev->regs[0x13] & 0x40) && (dev->regs[0x14] & 0x02);
can_write = (dev->regs[0x14] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
can_read = (dev->regs[0x14] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
can_write = (dev->regs[0x14] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
can_read = (dev->regs[0x14] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
for(i = 0; i < 8; i++)
{
base = 0xc0000 + (i << 15);
for (i = 0; i < 8; i++)
{
base = 0xc0000 + (i << 15);
if(dev->regs[0x13] & (1 << i))
mem_set_mem_state_both(base, 0x8000, can_read | can_write);
else
mem_set_mem_state_both(base, 0x8000, disabled_shadow);
if (dev->regs[0x13] & (1 << i))
mem_set_mem_state_both(base, 0x8000, can_read | can_write);
else
mem_set_mem_state_both(base, 0x8000, disabled_shadow);
}
}
flushmmucache();
flushmmucache();
}
static void
ali1429_write(uint16_t addr, uint8_t val, void *priv)
{
ali1429_t *dev = (ali1429_t *) priv;
ali1429_t *dev = (ali1429_t *)priv;
switch (addr) {
case 0x22:
dev->index = val;
break;
switch (addr)
{
case 0x22:
dev->index = val;
break;
case 0x23:
case 0x23:
if (dev->index != 0x03)
ali1429_log("M1429: dev->regs[%02x] = %02x\n", dev->index, val);
/* Don't log register unlock patterns */
if(dev->index != 0x03)
ali1429_log("M1429: dev->regs[%02x] = %02x\n", dev->index, val);
if (dev->index == 0x03)
dev->cfg_locked = !(val == 0xc5);
/* Unlock/Lock Registers */
if(dev->index == 0x03)
dev->cfg_locked = !(val == 0xc5);
if(!dev->cfg_locked)
if (!dev->cfg_locked)
{
dev->regs[dev->index] = val;
dev->regs[dev->index] = val;
switch(dev->index){
/* Shadow RAM */
switch (dev->index)
{
case 0x13:
case 0x14:
ali1429_shadow_recalc(dev);
break;
ali1429_shadow_recalc(dev);
break;
/* Cache */
case 0x18:
cpu_cache_ext_enabled = (val & 0x80);
break;
}
cpu_cache_ext_enabled = !!(val & 2);
cpu_update_waitstates();
break;
}
}
break;
break;
}
}
static uint8_t
ali1429_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
ali1429_t *dev = (ali1429_t *) priv;
switch (addr) {
case 0x23:
/* Do not conflict with Cyrix configuration registers */
if(!(((dev->index >= 0xc0) || (dev->index == 0x20)) && cpu_iscyrix))
ret = dev->regs[dev->index];
break;
}
return ret;
ali1429_t *dev = (ali1429_t *)priv;
return (addr == 0x23) ? dev->regs[dev->index] : 0xff;
}
static void
ali1429_close(void *priv)
{
ali1429_t *dev = (ali1429_t *) priv;
ali1429_t *dev = (ali1429_t *)priv;
free(dev);
}
static void *
ali1429_init(const device_t *info)
{
ali1429_t *dev = (ali1429_t *) malloc(sizeof(ali1429_t));
ali1429_t *dev = (ali1429_t *)malloc(sizeof(ali1429_t));
memset(dev, 0, sizeof(ali1429_t));
/*
@@ -168,26 +156,25 @@ ali1429_init(const device_t *info)
22h Index Port
23h Data Port
*/
io_sethandler(0x022, 0x0001, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, dev);
io_sethandler(0x023, 0x0001, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, dev);
io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, dev);
dev->cfg_locked = 1;
device_add(&apm_device);
device_add(&port_92_device);
dev->regs[0x13] = 0x00;
dev->regs[0x14] = 0x00;
ali1429_shadow_recalc(dev);
/* dev->smram = smram_add(); */
return dev;
}
const device_t ali1429_device = {
"ALi M1429",
0,
0,
ali1429_init, ali1429_close, NULL,
{ NULL }, NULL, NULL,
NULL
};
ali1429_init,
ali1429_close,
NULL,
{NULL},
NULL,
NULL,
NULL};

View File

@@ -12,7 +12,7 @@
*
* Authors: Tiseno100
*
* Copyright 2020 Tiseno100
* Copyright 2021 Tiseno100
*
*/
@@ -28,19 +28,15 @@
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/mem.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
typedef struct
{
uint8_t index,
regs[256];
port_92_t * port_92;
uint8_t index,
regs[256];
port_92_t *port_92;
} cs4031_t;
#ifdef ENABLE_CS4031_LOG
@@ -50,10 +46,11 @@ cs4031_log(const char *fmt, ...)
{
va_list ap;
if (cs4031_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
if (cs4031_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
@@ -62,139 +59,130 @@ cs4031_log(const char *fmt, ...)
static void cs4031_shadow_recalc(cs4031_t *dev)
{
mem_set_mem_state_both(0xa0000, 0x10000, (dev->regs[0x18] & 0x01) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
mem_set_mem_state_both(0xb0000, 0x10000, (dev->regs[0x18] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
uint32_t romc0000, romc4000, romc8000, romcc000, romd0000, rome0000, romf0000;
/* Register 18h */
if(dev->regs[0x18] & 0x01)
mem_set_mem_state_both(0xa0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
else
mem_set_mem_state_both(0xa0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
if(dev->regs[0x18] & 0x02)
mem_set_mem_state_both(0xb0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
else
mem_set_mem_state_both(0xb0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
/* Register 19h-1ah-1bh*/
shadowbios = (dev->regs[0x19] & 0x40);
shadowbios_write = (dev->regs[0x1a] & 0x40);
/* ROMCS only functions if shadow write is disabled */
romc0000 = ((dev->regs[0x1b] & 0x80) && (dev->regs[0x1b] & 0x01)) ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY;
romc4000 = ((dev->regs[0x1b] & 0x80) && (dev->regs[0x1b] & 0x02)) ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY;
romc8000 = ((dev->regs[0x1b] & 0x80) && (dev->regs[0x1b] & 0x04)) ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY;
romcc000 = ((dev->regs[0x1b] & 0x80) && (dev->regs[0x1b] & 0x08)) ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY;
romd0000 = ((dev->regs[0x1b] & 0x80) && (dev->regs[0x1b] & 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY;
rome0000 = ((dev->regs[0x1b] & 0x80) && (dev->regs[0x1b] & 0x20)) ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY;
romf0000 = ((dev->regs[0x1b] & 0x80) && (dev->regs[0x1b] & 0x40)) ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY;
mem_set_mem_state_both(0xc0000, 0x4000, ((dev->regs[0x19] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x1a] & 0x01) ? MEM_WRITE_INTERNAL : romc0000));
mem_set_mem_state_both(0xc4000, 0x4000, ((dev->regs[0x19] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x1a] & 0x02) ? MEM_WRITE_INTERNAL : romc4000));
mem_set_mem_state_both(0xc8000, 0x4000, ((dev->regs[0x19] & 0x04) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x1a] & 0x04) ? MEM_WRITE_INTERNAL : romc8000));
mem_set_mem_state_both(0xcc000, 0x4000, ((dev->regs[0x19] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x1a] & 0x08) ? MEM_WRITE_INTERNAL : romcc000));
mem_set_mem_state_both(0xd0000, 0x10000, ((dev->regs[0x19] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x1a] & 0x10) ? MEM_WRITE_INTERNAL : romd0000));
mem_set_mem_state_both(0xe0000, 0x10000, ((dev->regs[0x19] & 0x20) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x1a] & 0x20) ? MEM_WRITE_INTERNAL : rome0000));
mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[0x19] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x1a] & 0x40) ? MEM_WRITE_INTERNAL : romf0000));
for (uint32_t i = 0; i < 7; i++)
{
if (i < 4)
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, ((dev->regs[0x19] & (1 << i)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x1a] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
else
mem_set_mem_state_both(0xd0000 + ((i - 4) << 16), 0x10000, ((dev->regs[0x19] & (1 << i)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x1a] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
}
shadowbios = !!(dev->regs[0x19] & 0x40);
shadowbios_write = !!(dev->regs[0x1a] & 0x40);
}
static void
cs4031_write(uint16_t addr, uint8_t val, void *priv)
{
cs4031_t *dev = (cs4031_t *) priv;
cs4031_t *dev = (cs4031_t *)priv;
switch (addr) {
case 0x22:
dev->index = val;
break;
case 0x23:
switch (addr)
{
case 0x22:
dev->index = val;
break;
case 0x23:
cs4031_log("CS4031: dev->regs[%02x] = %02x\n", dev->index, val);
dev->regs[dev->index] = val;
switch(dev->index){
case 0x06:
cpu_update_waitstates();
switch (dev->index)
{
case 0x05:
dev->regs[dev->index] = val & 0x3f;
break;
case 0x18:
case 0x19:
case 0x1a:
case 0x1b:
case 0x06:
dev->regs[dev->index] = val & 0xbc;
break;
case 0x07:
dev->regs[dev->index] = val & 0x0f;
break;
case 0x10:
dev->regs[dev->index] = val & 0x3d;
break;
case 0x11:
dev->regs[dev->index] = val & 0x8d;
break;
case 0x12:
case 0x13:
dev->regs[dev->index] = val & 0x8d;
break;
case 0x14:
case 0x15:
case 0x16:
case 0x17:
dev->regs[dev->index] = val & 0x7f;
break;
case 0x18:
dev->regs[dev->index] = val & 0xf3;
cs4031_shadow_recalc(dev);
break;
case 0x1c:
if(dev->regs[0x1c] & 0x20)
port_92_add(dev->port_92);
else
port_92_remove(dev->port_92);
case 0x19:
case 0x1a:
dev->regs[dev->index] = val & 0x7f;
cs4031_shadow_recalc(dev);
break;
case 0x1b:
dev->regs[dev->index] = val;
break;
case 0x1c:
dev->regs[dev->index] = val & 0xb3;
port_92_set_features(dev->port_92, val & 0x10, val & 0x20);
break;
}
break;
break;
}
}
static uint8_t
cs4031_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
cs4031_t *dev = (cs4031_t *) priv;
cs4031_t *dev = (cs4031_t *)priv;
switch (addr) {
case 0x23:
ret = dev->regs[dev->index];
break;
}
return ret;
return (addr == 0x23) ? dev->regs[dev->index] : 0xff;
}
static void
cs4031_close(void *priv)
{
cs4031_t *dev = (cs4031_t *) priv;
cs4031_t *dev = (cs4031_t *)priv;
free(dev);
}
static void *
cs4031_init(const device_t *info)
{
cs4031_t *dev = (cs4031_t *) malloc(sizeof(cs4031_t));
cs4031_t *dev = (cs4031_t *)malloc(sizeof(cs4031_t));
memset(dev, 0, sizeof(cs4031_t));
dev->port_92 = device_add(&port_92_device);
io_sethandler(0x022, 0x0001, cs4031_read, NULL, NULL, cs4031_write, NULL, NULL, dev);
io_sethandler(0x023, 0x0001, cs4031_read, NULL, NULL, cs4031_write, NULL, NULL, dev);
dev->regs[0x05] = 0x05;
dev->regs[0x18] = 0x00;
dev->regs[0x19] = 0x00;
dev->regs[0x1a] = 0x00;
dev->regs[0x1b] = 0x60;
cs4031_shadow_recalc(dev);
io_sethandler(0x0022, 0x0002, cs4031_read, NULL, NULL, cs4031_write, NULL, NULL, dev);
return dev;
}
const device_t cs4031_device = {
"Chips & Technogies CS4031",
0,
0,
cs4031_init, cs4031_close, NULL,
{ NULL }, NULL, NULL,
NULL
};
cs4031_init,
cs4031_close,
NULL,
{NULL},
NULL,
NULL,
NULL};

View File

@@ -939,6 +939,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[0x7c] = val & 0x1f;
break;
}
break;
case 0x7d:
switch (dev->type) {
case INTEL_420TX: case INTEL_420ZX:
@@ -946,6 +947,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[0x7d] = val & 0x32;
break;
}
break;
case 0x7e: case 0x7f:
switch (dev->type) {
case INTEL_420TX: case INTEL_420ZX:
@@ -953,6 +955,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[addr] = val;
break;
}
break;
case 0x80:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:

View File

@@ -12,7 +12,7 @@
*
* Authors: Tiseno100
*
* Copyright 2020 Tiseno100
* Copyright 2021 Tiseno100
*
*/
@@ -28,130 +28,109 @@
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/mem.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
#define disabled_shadow (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
#ifdef ENABLE_OPTI283_LOG
int opti283_do_log = ENABLE_OPTI283_LOG;
static void
opti283_log(const char *fmt, ...)
{
va_list ap;
if (opti283_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define opti283_log(fmt, ...)
#endif
typedef struct
{
uint8_t index,
regs[256];
uint8_t index,
regs[256];
} opti283_t;
static void opti283_shadow_recalc(opti283_t *dev)
{
uint32_t base, i;
uint32_t shflagsc, shflagsd, shflagse, shflagsf;
mem_set_mem_state_both(0xf0000, 0x10000, (dev->regs[0x11] & 0x80) ? (MEM_READ_EXTANY | MEM_WRITE_INTERNAL) : (MEM_READ_INTERNAL | ((dev->regs[0x14] & 0x80) ? MEM_WRITE_INTERNAL : MEM_WRITE_DISABLED)));
shadowbios = !(dev->regs[0x11] & 0x80);
shadowbios_write = (dev->regs[0x11] & 0x80);
for (uint32_t i = 0; i < 4; i++)
{
if (dev->regs[0x11] & 0x40)
mem_set_mem_state_both(0xe0000 + (i << 14), 0x4000, (dev->regs[0x12] & (1 << (4 + i))) ? (MEM_READ_INTERNAL | ((dev->regs[0x11] & 4) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
mem_set_mem_state_both(0xe0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
if(dev->regs[0x11] & 0x10){
shflagsc = MEM_READ_INTERNAL;
shflagsc |= (dev->regs[0x11] & 0x08) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
} else shflagsc = disabled_shadow;
if(dev->regs[0x11] & 0x20){
shflagsd = MEM_READ_INTERNAL;
shflagsd |= (dev->regs[0x11] & 0x08) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
} else shflagsd = disabled_shadow;
if(dev->regs[0x11] & 0x40){
shflagse = MEM_READ_INTERNAL;
shflagse |= (dev->regs[0x11] & 0x08) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
} else shflagse = disabled_shadow;
if(!(dev->regs[0x11] & 0x80)){
shflagsf = MEM_READ_INTERNAL | MEM_WRITE_DISABLED;
} else shflagsf = MEM_READ_EXTANY | MEM_WRITE_INTERNAL;
mem_set_mem_state_both(0xf0000, 0x10000, shflagsf);
for(i = 4; i < 8; i++){
base = 0xc0000 + ((i-4) << 14);
mem_set_mem_state_both(base, 0x4000, (dev->regs[0x13] & (1 << i)) ? shflagsc : disabled_shadow);
}
for(i = 0; i < 4; i++){
base = 0xd0000 + (i << 14);
mem_set_mem_state_both(base, 0x4000, (dev->regs[0x12] & (1 << i)) ? shflagsd : disabled_shadow);
}
for(i = 4; i < 8; i++){
base = 0xe0000 + ((i-4) << 14);
mem_set_mem_state_both(base, 0x4000, (dev->regs[0x12] & (1 << i)) ? shflagse : disabled_shadow);
}
if (dev->regs[0x11] & 0x20)
mem_set_mem_state_both(0xd0000 + (i << 14), 0x4000, (dev->regs[0x12] & (1 << i)) ? (MEM_READ_INTERNAL | ((dev->regs[0x11] & 2) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
else
mem_set_mem_state_both(0xd0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
if (dev->regs[0x11] & 0x10)
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, (dev->regs[0x13] & (1 << (4 + i))) ? (MEM_READ_INTERNAL | ((dev->regs[0x11] & 1) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
else
mem_set_mem_state_both(0xc0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
}
}
static void
opti283_write(uint16_t addr, uint8_t val, void *priv)
{
opti283_t *dev = (opti283_t *) priv;
opti283_t *dev = (opti283_t *)priv;
switch (addr) {
case 0x22:
dev->index = val;
break;
case 0x24:
/* pclog("OPTi 283: dev->regs[%02x] = %02x\n", dev->index, val); */
dev->regs[dev->index] = val;
switch (addr)
{
case 0x22:
dev->index = val;
break;
case 0x24:
opti283_log("OPTi 283: dev->regs[%02x] = %02x\n", dev->index, val);
switch(dev->index){
case 0x10:
cpu_update_waitstates();
switch (dev->index)
{
case 0x10:
dev->regs[dev->index] = val;
break;
case 0x11:
case 0x12:
case 0x13:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
dev->regs[dev->index] = val;
opti283_shadow_recalc(dev);
break;
}
break;
break;
}
}
static uint8_t
opti283_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
opti283_t *dev = (opti283_t *) priv;
switch (addr) {
case 0x24:
ret = dev->regs[dev->index];
break;
}
return ret;
opti283_t *dev = (opti283_t *)priv;
return (addr == 0x24) ? dev->regs[dev->index] : 0xff;
}
static void
opti283_close(void *priv)
{
opti283_t *dev = (opti283_t *) priv;
opti283_t *dev = (opti283_t *)priv;
free(dev);
}
static void *
opti283_init(const device_t *info)
{
opti283_t *dev = (opti283_t *) malloc(sizeof(opti283_t));
opti283_t *dev = (opti283_t *)malloc(sizeof(opti283_t));
memset(dev, 0, sizeof(opti283_t));
io_sethandler(0x022, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
io_sethandler(0x024, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
io_sethandler(0x0022, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
io_sethandler(0x0024, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
dev->regs[0x10] = 0x3f;
dev->regs[0x11] = 0xf0;
@@ -160,12 +139,14 @@ opti283_init(const device_t *info)
return dev;
}
const device_t opti283_device = {
"OPTi 82C283",
0,
0,
opti283_init, opti283_close, NULL,
{ NULL }, NULL, NULL,
NULL
};
opti283_init,
opti283_close,
NULL,
{NULL},
NULL,
NULL,
NULL};

View File

@@ -8,9 +8,10 @@
*
* Implementation of the OPTi 82C291 chipset.
* Authors: plant/nerd73
* Authors: plant/nerd73, Tiseno100
*
* Copyright 2020 plant/nerd73.
* Copyright 2021 Tiseno100.
*/
#include <stdarg.h>
#include <stdint.h>
@@ -24,133 +25,135 @@
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/mem.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
#ifdef ENABLE_OPTI291_LOG
int opti291_do_log = ENABLE_OPTI291_LOG;
static void
opti291_log(const char *fmt, ...)
{
va_list ap;
if (opti291_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define opti291_log(fmt, ...)
#endif
typedef struct
{
uint8_t index,
regs[256];
port_92_t *port_92;
uint8_t index, regs[256];
port_92_t *port_92;
} opti291_t;
static void opti291_recalc(opti291_t *dev)
{
uint32_t base;
uint32_t i, shflags, write, writef = 0;
mem_set_mem_state_both(0xf0000, 0x10000, (!(dev->regs[0x23] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x27] & 0x80) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL));
writef = (dev->regs[0x27] & 0x80) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
if (!(dev->regs[0x23] & 0x40))
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | writef);
else
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY | writef);
for (i = 0; i < 4; i++) {
base = 0xe0000 + (i << 14);
shflags = (dev->regs[0x24] & (1 << (i+4))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
write = (dev->regs[0x24] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
shflags |= (dev->regs[0x27] & 0x40) ? MEM_WRITE_DISABLED : write;
mem_set_mem_state(base, 0x4000, shflags);
for (uint32_t i = 0; i < 4; i++)
{
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, ((dev->regs[0x26] & (1 << (i + 4))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x27] & 0x10) ? MEM_WRITE_DISABLED : ((dev->regs[0x26] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)));
mem_set_mem_state_both(0xd0000 + (i << 14), 0x4000, ((dev->regs[0x25] & (1 << (i + 4))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x27] & 0x20) ? MEM_WRITE_DISABLED : ((dev->regs[0x25] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)));
mem_set_mem_state_both(0xe0000 + (i << 14), 0x4000, ((dev->regs[0x24] & (1 << (i + 4))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x27] & 0x40) ? MEM_WRITE_DISABLED : ((dev->regs[0x24] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)));
}
for (i = 0; i < 4; i++) {
base = 0xd0000 + (i << 14);
shflags = (dev->regs[0x25] & (1 << (i+4))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
write = (dev->regs[0x25] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
shflags |= (dev->regs[0x27] & 0x20) ? MEM_WRITE_DISABLED : write;
mem_set_mem_state(base, 0x4000, shflags);
}
for (i = 0; i < 4; i++) {
base = 0xc0000 + (i << 14);
shflags = (dev->regs[0x26] & (1 << (i+4))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
write = (dev->regs[0x26] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
shflags |= (dev->regs[0x27] & 0x10) ? MEM_WRITE_DISABLED : write;
mem_set_mem_state(base, 0x4000, shflags);
}
flushmmucache();
flushmmucache();
}
static void
opti291_write(uint16_t addr, uint8_t val, void *priv)
{
opti291_t *dev = (opti291_t *) priv;
opti291_t *dev = (opti291_t *)priv;
switch (addr) {
switch (addr)
{
case 0x22:
dev->index = val;
break;
case 0x24:
pclog("OPTi 291: dev->regs[%02x] = %02x\n", dev->index, val);
dev->regs[dev->index] = val;
switch(dev->index){
case 0x21:
cpu_update_waitstates();
break;
case 0x23:
case 0x24:
case 0x25:
case 0x26:
case 0x27:
opti291_recalc(dev);
break;
}
opti291_log("OPTi 291: dev->regs[%02x] = %02x\n", dev->index, val);
switch (dev->index)
{
case 0x20:
dev->regs[dev->index] = val & 0x3f;
break;
case 0x21:
dev->regs[dev->index] = val & 0xf3;
break;
case 0x22:
dev->regs[dev->index] = val;
break;
case 0x23:
case 0x24:
case 0x25:
case 0x26:
dev->regs[dev->index] = val;
opti291_recalc(dev);
break;
case 0x27:
case 0x28:
dev->regs[dev->index] = val;
break;
case 0x29:
dev->regs[dev->index] = val & 0x0f;
break;
case 0x2a:
case 0x2b:
case 0x2c:
dev->regs[dev->index] = val;
break;
}
break;
}
}
}
static uint8_t
opti291_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
opti291_t *dev = (opti291_t *) priv;
opti291_t *dev = (opti291_t *)priv;
switch (addr) {
case 0x24:
// pclog("OPTi 291: read from dev->regs[%02x]\n", dev->index);
ret = dev->regs[dev->index];
break;
}
return ret;
return (addr == 0x24) ? dev->regs[dev->index] : 0xff;
}
static void
opti291_close(void *priv)
{
opti291_t *dev = (opti291_t *) priv;
opti291_t *dev = (opti291_t *)priv;
free(dev);
free(dev);
}
static void *
opti291_init(const device_t *info)
{
opti291_t *dev = (opti291_t *) malloc(sizeof(opti291_t));
memset(dev, 0, sizeof(opti291_t));
opti291_t *dev = (opti291_t *)malloc(sizeof(opti291_t));
memset(dev, 0, sizeof(opti291_t));
io_sethandler(0x022, 0x0001, opti291_read, NULL, NULL, opti291_write, NULL, NULL, dev);
io_sethandler(0x024, 0x0001, opti291_read, NULL, NULL, opti291_write, NULL, NULL, dev);
dev->regs[0x23] = 0x40;
dev->port_92 = device_add(&port_92_device);
opti291_recalc(dev);
io_sethandler(0x022, 0x0001, opti291_read, NULL, NULL, opti291_write, NULL, NULL, dev);
io_sethandler(0x024, 0x0001, opti291_read, NULL, NULL, opti291_write, NULL, NULL, dev);
dev->regs[0x22] = 0xf0;
dev->regs[0x23] = 0x40;
dev->regs[0x28] = 0x08;
dev->regs[0x29] = 0xa0;
device_add(&port_92_device);
opti291_recalc(dev);
return dev;
return dev;
}
const device_t opti291_device = {
"OPTi 82C291",
0,
0,
opti291_init, opti291_close, NULL,
{ NULL }, NULL, NULL,
NULL
};
"OPTi 82C291",
0,
0,
opti291_init,
opti291_close,
NULL,
{NULL},
NULL,
NULL,
NULL};

View File

@@ -210,7 +210,7 @@ memory_pci_bridge_write(int func, int addr, uint8_t val, void *priv)
dev->pci_conf[addr] = val & 0xec;
break;
case 0x51: /* Cache */
case 0x51: /* L2 Cache */
dev->pci_conf[addr] = val;
cpu_cache_ext_enabled = !!(val & 0x40);
cpu_update_waitstates();
@@ -263,7 +263,7 @@ memory_pci_bridge_write(int func, int addr, uint8_t val, void *priv)
case 0x83:
dev->pci_conf[addr] = val;
port_92_set_features(dev->port_92, (val & 0x40), (val & 0x80));
port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80));
break;
case 0x87:
@@ -272,7 +272,9 @@ memory_pci_bridge_write(int func, int addr, uint8_t val, void *priv)
case 0x93: /* APM SMI */
dev->pci_conf[addr] = val;
apm_set_do_smi(dev->apm, ((dev->pci_conf[0x9b] & 0x01) && (val & 0x02)));
apm_set_do_smi(dev->apm, !!((dev->pci_conf[0x9b] & 0x01) && (val & 0x02)));
if (val & 0x02)
dev->pci_conf[0x9d] |= 1;
break;
case 0x94:
@@ -326,7 +328,7 @@ pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv)
case 0x43:
case 0x44:
dev->pci_conf_sb[0][addr] = val & 0x8f;
pci_set_irq_routing(PCI_INTA + (val & 0x07), !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED);
pci_set_irq_routing((addr & 0x07), !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED);
break;
case 0x45:
@@ -415,7 +417,7 @@ pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv)
}
sis_5571_log("IDE Controller: dev->pci_conf[%02x] = %02x\n", addr, val);
if ((addr == 0x09) || ((addr >= 0x10) && (addr <= 0x23)) || (addr == 0x4a))
if (((addr >= 0x09) && (addr <= 0x23)) || (addr == 0x4a))
sis_5571_ide_handler(dev);
break;
@@ -593,7 +595,6 @@ sis_5571_init(const device_t *info)
pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev);
dev->sb_pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev);
pci_enable_mirq(1);
/* APM */
dev->apm = device_add(&apm_pci_device);
@@ -601,16 +602,19 @@ sis_5571_init(const device_t *info)
/* DMA */
dma_alias_set();
/* MIRQ */
pci_enable_mirq(0);
/* Port 92 & SMRAM */
dev->port_92 = device_add(&port_92_pci_device);
dev->smram = smram_add();
/* SFF IDE */
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
dev->program_status_pri = 0;
dev->program_status_sec = 0;
/* Port 92 & SMRAM */
dev->port_92 = device_add(&port_92_pci_device);
dev->smram = smram_add();
/* USB */
dev->usb = device_add(&usb_device);

View File

@@ -6,234 +6,424 @@
*
* This file is part of the 86Box distribution.
*
* Implementation of the WD76C10 System Controller chip.
* Implementation of the Western Digital WD76C10 chipset.
*
* Note: This chipset has no datasheet, everything were done via
* reverse engineering the BIOS of various machines using it.
*
* Authors: Tiseno100
*
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Copyright 2021 Tiseno100
*
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
* Copyright 2017-2019 Fred N. van Kempen.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/keyboard.h>
#include <86box/device.h>
#include <86box/dma.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/hdd.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/lpt.h>
#include <86box/mem.h>
#include <86box/port_92.h>
#include <86box/serial.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/video.h>
#include <86box/chipset.h>
/* Lock/Unlock Procedures */
#define LOCK dev->lock
#define UNLOCKED !dev->lock
typedef struct {
int type;
#define ENABLE_WD76C10_LOG 1
uint16_t reg_0092;
uint16_t reg_2072;
uint16_t reg_2872;
uint16_t reg_5872;
#ifdef ENABLE_WD76C10_LOG
int wd76c10_do_log = ENABLE_WD76C10_LOG;
static void
wd76c10_log(const char *fmt, ...)
{
va_list ap;
uint16_t reg_f872;
if (wd76c10_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define wd76c10_log(fmt, ...)
#endif
serial_t *uart[2];
typedef struct
{
uint16_t lock_reg, oscillator_40mhz, cache_flush, ems_page_reg,
ems_page_reg_pointer, port_shadow, pmc_interrupt,
high_mem_protect_boundry, delay_line, diagnostic,
nmi_status, pmc_input, pmc_timer,
pmc_output, ems_control_low_address_boundry, shadow_ram,
split_addr, bank32staddr, bank10staddr,
non_page_mode_dram_timing, mem_control,
refresh_control, disk_chip_select, prog_chip_sel_addr,
bus_timing_power_down_ctl, clk_control;
fdc_t *fdc;
int lock;
mem_mapping_t extram_mapping;
uint8_t extram[65536];
fdc_t *fdc_controller;
mem_mapping_t *mem_mapping;
serial_t *uart[2];
} wd76c10_t;
static void wd76c10_refresh_control(wd76c10_t *dev)
{
serial_remove(dev->uart[1]);
/* Serial B */
switch ((dev->refresh_control >> 1) & 7)
{
case 1:
serial_setup(dev->uart[1], 0x3f8, 3);
break;
case 2:
serial_setup(dev->uart[1], 0x2f8, 3);
break;
case 3:
serial_setup(dev->uart[1], 0x3e8, 3);
break;
case 4:
serial_setup(dev->uart[1], 0x2e8, 3);
break;
}
serial_remove(dev->uart[0]);
/* Serial A */
switch ((dev->refresh_control >> 5) & 7)
{
case 1:
serial_setup(dev->uart[0], 0x3f8, 4);
break;
case 2:
serial_setup(dev->uart[0], 0x2f8, 4);
break;
case 3:
serial_setup(dev->uart[0], 0x3e8, 4);
break;
case 4:
serial_setup(dev->uart[0], 0x2e8, 4);
break;
}
lpt1_remove();
/* LPT */
switch ((dev->refresh_control >> 9) & 3)
{
case 1:
lpt1_init(0x3bc);
lpt1_irq(7);
break;
case 2:
lpt1_init(0x378);
lpt1_irq(7);
break;
case 3:
lpt1_init(0x278);
lpt1_irq(7);
break;
}
}
static void wd76c10_split_addr(wd76c10_t *dev)
{
switch ((dev->split_addr >> 8) & 3)
{
case 1:
if (((dev->shadow_ram >> 8) & 3) == 2)
mem_remap_top(256);
break;
case 2:
if (((dev->shadow_ram >> 8) & 3) == 1)
mem_remap_top(320);
break;
case 3:
if (((dev->shadow_ram >> 8) & 3) == 3)
mem_remap_top(384);
break;
}
}
static void wd76c10_disk_chip_select(wd76c10_t *dev)
{
ide_pri_disable();
if (!(dev->disk_chip_select & 1))
{
ide_set_base(0, !(dev->disk_chip_select & 0x0010) ? 0x1f0 : 0x170);
ide_set_side(0, !(dev->disk_chip_select & 0x0010) ? 0x3f6 : 0x376);
}
ide_pri_enable();
fdc_remove(dev->fdc_controller);
if (!(dev->disk_chip_select & 2))
fdc_set_base(dev->fdc_controller, !(dev->disk_chip_select & 0x0010) ? 0x3f0 : 0x370);
}
static void wd76c10_shadow_recalc(wd76c10_t *dev)
{
switch ((dev->shadow_ram >> 14) & 3)
{
case 0:
mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
case 1:
mem_set_mem_state_both(0x80000, 0x20000, MEM_READ_DISABLED | MEM_WRITE_DISABLED);
break;
case 2:
mem_set_mem_state_both(0x40000, 0x60000, MEM_READ_DISABLED | MEM_WRITE_DISABLED);
break;
case 3:
mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | MEM_WRITE_DISABLED);
break;
}
switch ((dev->shadow_ram >> 8) & 3)
{
case 0:
mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
mem_set_mem_state_both(0xc0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
break;
case 1:
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL));
break;
case 2:
mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_INTERNAL | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL));
break;
case 3:
mem_set_mem_state_both(0x20000, 0x80000, MEM_READ_DISABLED | (!!(dev->shadow_ram & 0x1000) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL));
break;
}
}
static void
wd76c10_write(uint16_t addr, uint16_t val, void *priv)
{
wd76c10_t *dev = (wd76c10_t *)priv;
if (UNLOCKED)
{
switch (addr)
{
case 0x1072:
dev->clk_control = val;
break;
case 0x1872:
dev->bus_timing_power_down_ctl = val;
break;
case 0x2072:
dev->refresh_control = val;
wd76c10_refresh_control(dev);
break;
case 0x2872:
dev->disk_chip_select = val;
wd76c10_disk_chip_select(dev);
break;
case 0x3072:
dev->prog_chip_sel_addr = val;
break;
case 0x3872:
dev->non_page_mode_dram_timing = val;
break;
case 0x4072:
dev->mem_control = val;
break;
case 0x4872:
dev->bank10staddr = val;
break;
case 0x5072:
dev->bank32staddr = val;
break;
case 0x5872:
dev->split_addr = val;
wd76c10_split_addr(dev);
break;
case 0x6072:
dev->shadow_ram = val & 0xffbf;
wd76c10_shadow_recalc(dev);
break;
case 0x6872:
dev->ems_control_low_address_boundry = val & 0xecff;
break;
case 0x7072:
dev->pmc_output = (val >> 8) & 0x00ff;
break;
case 0x7872:
dev->pmc_output = val & 0xff00;
break;
case 0x8072:
dev->pmc_timer = val;
break;
case 0x8872:
dev->pmc_input = val;
break;
case 0x9072:
dev->nmi_status = val & 0x00fc;
break;
case 0x9872:
dev->diagnostic = val & 0xfdff;
break;
case 0xa072:
dev->delay_line = val;
break;
case 0xc872:
dev->pmc_interrupt = val & 0xfcfc;
break;
case 0xf072:
dev->oscillator_40mhz = 0;
break;
case 0xf472:
dev->oscillator_40mhz = 1;
break;
case 0xf872:
dev->cache_flush = val;
flushmmucache();
break;
}
wd76c10_log("WD76C10: dev->regs[%04x] = %04x\n", addr, val);
}
switch (addr)
{
case 0xe072:
dev->ems_page_reg_pointer = val & 0x003f;
break;
case 0xe872:
dev->ems_page_reg = val & 0x8fff;
break;
case 0xf073:
dev->lock_reg = val & 0x00ff;
LOCK = !(val && 0x00da);
break;
}
}
static uint16_t
wd76c10_read(uint16_t port, void *priv)
wd76c10_read(uint16_t addr, void *priv)
{
wd76c10_t *dev = (wd76c10_t *)priv;
int16_t ret = 0xffff;
wd76c10_log("WD76C10: R dev->regs[%04x]\n", addr);
switch (addr)
{
case 0x1072:
return dev->clk_control;
switch (port) {
case 0x2072:
ret = dev->reg_2072;
break;
case 0x1872:
return dev->bus_timing_power_down_ctl;
case 0x2872:
ret = dev->reg_2872;
break;
case 0x2072:
return dev->refresh_control;
case 0x5872:
ret = dev->reg_5872;
break;
case 0x2872:
return dev->disk_chip_select;
case 0xf872:
ret = dev->reg_f872;
break;
}
case 0x3072:
return dev->prog_chip_sel_addr;
return(ret);
}
case 0x3872:
return dev->non_page_mode_dram_timing;
case 0x4072:
return dev->mem_control;
static void
wd76c10_write(uint16_t port, uint16_t val, void *priv)
{
wd76c10_t *dev = (wd76c10_t *)priv;
case 0x4872:
return dev->bank10staddr;
switch (port) {
case 0x2072:
dev->reg_2072 = val;
case 0x5072:
return dev->bank32staddr;
serial_remove(dev->uart[0]);
if (!(val & 0x10))
{
switch ((val >> 5) & 7)
{
case 1: serial_setup(dev->uart[0], 0x3f8, 4); break;
case 2: serial_setup(dev->uart[0], 0x2f8, 4); break;
case 3: serial_setup(dev->uart[0], 0x3e8, 4); break;
case 4: serial_setup(dev->uart[0], 0x2e8, 4); break;
default: break;
}
}
serial_remove(dev->uart[1]);
if (!(val & 0x01))
{
switch ((val >> 1) & 7)
{
case 1: serial_setup(dev->uart[1], 0x3f8, 3); break;
case 2: serial_setup(dev->uart[1], 0x2f8, 3); break;
case 3: serial_setup(dev->uart[1], 0x3e8, 3); break;
case 4: serial_setup(dev->uart[1], 0x2e8, 3); break;
default: break;
}
}
break;
case 0x5872:
return dev->split_addr;
case 0x2872:
dev->reg_2872 = val;
case 0x6072:
return dev->shadow_ram;
fdc_remove(dev->fdc);
if (! (val & 1))
fdc_set_base(dev->fdc, 0x03f0);
break;
case 0x6872:
return dev->ems_control_low_address_boundry;
case 0x5872:
dev->reg_5872 = val;
break;
case 0x7072:
return (dev->pmc_output << 8) & 0xff00;
case 0xf872:
dev->reg_f872 = val;
switch (val & 3) {
case 0:
mem_set_mem_state(0xd0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
break;
case 1:
mem_set_mem_state(0xd0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
break;
case 2:
mem_set_mem_state(0xd0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
break;
case 3:
mem_set_mem_state(0xd0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
}
flushmmucache_nopc();
if (val & 4)
mem_mapping_enable(&dev->extram_mapping);
else
mem_mapping_disable(&dev->extram_mapping);
flushmmucache_nopc();
break;
case 0x7872:
return (dev->pmc_output) & 0xff00;
case 0x8072:
return dev->pmc_timer;
case 0x8872:
return dev->pmc_input;
case 0x9072:
return dev->nmi_status;
case 0x9872:
return dev->diagnostic;
case 0xa072:
return dev->delay_line;
case 0xb872:
return (inb(0x040b) << 8) | inb(0x04d6);
case 0xc872:
return dev->pmc_interrupt;
case 0xd072:
return dev->port_shadow;
case 0xe072:
return dev->ems_page_reg_pointer;
case 0xe872:
return dev->ems_page_reg;
case 0xfc72:
return 0x0ff0;
default:
return 0xffff;
}
}
static uint8_t
wd76c10_readb(uint16_t port, void *priv)
{
if (port & 1)
return(wd76c10_read(port & ~1, priv) >> 8);
return(wd76c10_read(port, priv) & 0xff);
}
static void
wd76c10_writeb(uint16_t port, uint8_t val, void *priv)
{
uint16_t temp = wd76c10_read(port, priv);
if (port & 1)
wd76c10_write(port & ~1, (temp & 0x00ff) | (val << 8), priv);
else
wd76c10_write(port , (temp & 0xff00) | val, priv);
}
uint8_t
wd76c10_read_extram(uint32_t addr, void *priv)
{
wd76c10_t *dev = (wd76c10_t *)priv;
return dev->extram[addr & 0xffff];
}
uint16_t
wd76c10_read_extramw(uint32_t addr, void *priv)
{
wd76c10_t *dev = (wd76c10_t *)priv;
return *(uint16_t *)&dev->extram[addr & 0xffff];
}
uint32_t
wd76c10_read_extraml(uint32_t addr, void *priv)
{
wd76c10_t *dev = (wd76c10_t *)priv;
return *(uint32_t *)&dev->extram[addr & 0xffff];
}
void
wd76c10_write_extram(uint32_t addr, uint8_t val, void *priv)
{
wd76c10_t *dev = (wd76c10_t *)priv;
dev->extram[addr & 0xffff] = val;
}
void
wd76c10_write_extramw(uint32_t addr, uint16_t val, void *priv)
{
wd76c10_t *dev = (wd76c10_t *)priv;
*(uint16_t *)&dev->extram[addr & 0xffff] = val;
}
void
wd76c10_write_extraml(uint32_t addr, uint32_t val, void *priv)
{
wd76c10_t *dev = (wd76c10_t *)priv;
*(uint32_t *)&dev->extram[addr & 0xffff] = val;
}
static void
wd76c10_close(void *priv)
{
@@ -242,51 +432,119 @@ wd76c10_close(void *priv)
free(dev);
}
static void *
wd76c10_init(const device_t *info)
{
wd76c10_t *dev;
wd76c10_t *dev = (wd76c10_t *)malloc(sizeof(wd76c10_t));
memset(dev, 0, sizeof(wd76c10_t));
dev = (wd76c10_t *) malloc(sizeof(wd76c10_t));
memset(dev, 0x00, sizeof(wd76c10_t));
dev->type = info->local;
device_add(&port_92_inv_device);
dev->uart[0] = device_add_inst(&ns16450_device, 1);
dev->uart[1] = device_add_inst(&ns16450_device, 2);
dev->fdc_controller = device_add(&fdc_at_device);
device_add(&ide_isa_device);
dev->fdc = (fdc_t *)device_add(&fdc_at_device);
/* Lock Configuration */
LOCK = 1;
dev->uart[0] = device_add_inst(&i8250_device, 1);
dev->uart[1] = device_add_inst(&i8250_device, 2);
/* Clock Control */
io_sethandler(0x1072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
device_add(&port_92_word_device);
/* Bus Timing & Power Down Control */
io_sethandler(0x1872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
io_sethandler(0x2072, 2,
wd76c10_readb,wd76c10_read,NULL,
wd76c10_writeb,wd76c10_write,NULL, dev);
io_sethandler(0x2872, 2,
wd76c10_readb,wd76c10_read,NULL,
wd76c10_writeb,wd76c10_write,NULL, dev);
io_sethandler(0x5872, 2,
wd76c10_readb,wd76c10_read,NULL,
wd76c10_writeb,wd76c10_write,NULL, dev);
io_sethandler(0xf872, 2,
wd76c10_readb,wd76c10_read,NULL,
wd76c10_writeb,wd76c10_write,NULL, dev);
/* Refresh Control(Serial & Parallel) */
io_sethandler(0x2072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
mem_mapping_add(&dev->extram_mapping, 0xd0000, 0x10000,
wd76c10_read_extram,wd76c10_read_extramw,wd76c10_read_extraml,
wd76c10_write_extram,wd76c10_write_extramw,wd76c10_write_extraml,
dev->extram, MEM_MAPPING_EXTERNAL, dev);
mem_mapping_disable(&dev->extram_mapping);
/* Disk Chip Select */
io_sethandler(0x2872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
return(dev);
/* Programmable Chip Select Address(Needs more further examination!) */
io_sethandler(0x3072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* Bank 1 & 0 Start Address */
io_sethandler(0x4872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* Bank 3 & 2 Start Address */
io_sethandler(0x5072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* Split Address */
io_sethandler(0x5872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* EMS Control & EMS Low level boundry */
io_sethandler(0x6072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* EMS Control & EMS Low level boundry */
io_sethandler(0x6872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* PMC Output */
io_sethandler(0x7072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* PMC Output */
io_sethandler(0x7872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* PMC Status */
io_sethandler(0x8072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* PMC Status */
io_sethandler(0x8872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* NMI Status (Needs further checkup) */
io_sethandler(0x9072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* Diagnostics */
io_sethandler(0x9872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* Delay Line */
io_sethandler(0xa072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* DMA Mode Shadow(Needs Involvement on the DMA code) */
io_sethandler(0xb872, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev);
/* High Memory Protection Boundry */
io_sethandler(0xc072, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev);
/* PMC Interrupt Enable */
io_sethandler(0xc872, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev);
/* Port Shadow (Needs further lookup) */
io_sethandler(0xd072, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev);
/* EMS Page Register Pointer */
io_sethandler(0xe072, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* EMS Page Register */
io_sethandler(0xe872, 1, NULL, wd76c10_read, NULL, NULL, wd76c10_write, NULL, dev);
/* Lock/Unlock Configuration */
io_sethandler(0xf073, 1, NULL, NULL, NULL, NULL, wd76c10_write, NULL, dev);
/* 40Mhz Oscillator Enable Disable */
io_sethandler(0xf072, 1, NULL, NULL, NULL, NULL, wd76c10_write, NULL, dev);
io_sethandler(0xf472, 1, NULL, NULL, NULL, NULL, wd76c10_write, NULL, dev);
/* Lock Status */
io_sethandler(0xfc72, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev);
/* Cache Flush */
io_sethandler(0xf872, 1, NULL, wd76c10_read, NULL, NULL, NULL, NULL, dev);
dma_ext_mode_init();
wd76c10_shadow_recalc(dev);
wd76c10_refresh_control(dev);
wd76c10_disk_chip_select(dev);
return dev;
}
const device_t wd76c10_device = {
"WD 76C10",
"Western Digital WD76C10",
0,
0,
wd76c10_init, wd76c10_close, NULL,
{ NULL }, NULL, NULL,
NULL
};
wd76c10_init,
wd76c10_close,
NULL,
{NULL},
NULL,
NULL,
NULL};

View File

@@ -2653,9 +2653,11 @@ void cpu_RDMSR()
{
case 0x1000:
EAX = ibm_por_msr & 0xfeff;
break;
case 0x1001:
EAX = ibm_crcr_msr & 0xffffffffff;
break;
}
break;
@@ -2666,13 +2668,16 @@ void cpu_RDMSR()
{
case 0x1000:
EAX = ibm_por_msr & 0xffeff;
break;
case 0x1001:
EAX = ibm_crcr_msr & 0xffffffffff;
break;
if (cpu_s->multi) {
case 0x1002:
EAX = ibm_por2_msr & 0x3f000000;
break;
}
}
break;

View File

@@ -17,7 +17,7 @@ add_library(dev OBJECT bugger.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c
hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c
postcard.c serial.c vpc2007.c clock_ics9xxx.c i2c.c i2c_gpio.c
smbus_piix4.c keyboard.c keyboard_xt.c keyboard_at.c mouse.c mouse_bus.c
mouse_serial.c mouse_ps2.c phoenix_486_jumper.c olivetti_m290_registers.c)
mouse_serial.c mouse_ps2.c phoenix_486_jumper.c)
if(LASERXT)
target_compile_definitions(dev PRIVATE USE_LASERXT)

View File

@@ -13,5 +13,5 @@
# Copyright 2020,2021 David Hrdlička.
#
add_library(fdd OBJECT fdd.c fdc.c fdc_pii15xb.c fdi2raw.c fdd_common.c
add_library(fdd OBJECT fdd.c fdc.c fdc_magitronic.c fdc_pii15xb.c fdi2raw.c fdd_common.c
fdd_86f.c fdd_fdi.c fdd_imd.c fdd_img.c fdd_json.c fdd_mfm.c fdd_td0.c)

View File

@@ -109,6 +109,7 @@ typedef const struct {
/* All emulated machines have at least one integrated FDC controller */
static fdc_cards_t fdc_cards[] = {
{ "internal", NULL },
{ "b215", &fdc_b215_device },
{ "dtk_pii151b", &fdc_pii151b_device },
{ "dtk_pii158b", &fdc_pii158b_device },
{ "", NULL },
@@ -2170,20 +2171,20 @@ fdc_set_base(fdc_t *fdc, int base)
io_sethandler(base + 4, 0x0002, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) {
io_sethandler(base + (super_io ? 2 : 0), super_io ? 0x0004 : 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if (fdc->flags & FDC_FLAG_PCJR)
io_sethandler(base, 0x0010, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
else {
io_sethandler(base + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc);
io_sethandler(base + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
if (fdc->flags & FDC_FLAG_TOSHIBA)
io_sethandler(base + 0x0007, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
}
}
if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) {
io_sethandler(base + (super_io ? 2 : 0), super_io ? 0x0004 : 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if (fdc->flags & FDC_FLAG_PCJR)
io_sethandler(base, 0x0010, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
else {
io_sethandler(base + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc);
io_sethandler(base + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
if (fdc->flags & FDC_FLAG_TOSHIBA)
io_sethandler(base + 0x0007, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
}
}
}
fdc->base_address = base;
fdc_log("FDC Base address set%s (%04X)\n", super_io ? " for Super I/O" : "", fdc->base_address);
@@ -2201,21 +2202,21 @@ fdc_remove(fdc_t *fdc)
io_removehandler(fdc->base_address + 4, 0x0002, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) {
io_removehandler(fdc->base_address + (super_io ? 2 : 0), super_io ? 0x0004 : 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if (fdc->flags & FDC_FLAG_PCJR)
io_removehandler(fdc->base_address, 0x0010, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
else {
io_removehandler(fdc->base_address + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
if (fdc->flags & FDC_FLAG_TOSHIBA)
io_removehandler(fdc->base_address + 0x0007, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
}
}
if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) {
io_removehandler(fdc->base_address + (super_io ? 2 : 0), super_io ? 0x0004 : 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if (fdc->flags & FDC_FLAG_PCJR)
io_removehandler(fdc->base_address, 0x0010, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
else {
io_removehandler(fdc->base_address + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
if (fdc->flags & FDC_FLAG_TOSHIBA)
io_removehandler(fdc->base_address + 0x0007, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
}
}
}
}
@@ -2438,7 +2439,7 @@ const device_t fdc_at_nsc_device = {
const device_t fdc_dp8473_device = {
"NS DP8473 Floppy Drive Controller",
0,
FDC_FLAG_NSDP,
FDC_FLAG_AT | FDC_FLAG_NSC,
fdc_init,
fdc_close,
fdc_reset,

View File

@@ -0,0 +1,99 @@
/*
* 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.
*
* Implementation of the Magitronic B215 XT-FDC Controller.
*
* Authors: Tiseno100
*
* Copyright 2021 Tiseno100
*
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#define ROM_B215 L"roms/floppy/magitronic/Magitronic B215 - BIOS ROM.bin"
#define ROM_ADDR (uint32_t)(device_get_config_hex20("bios_addr") & 0x000fffff)
typedef struct
{
fdc_t *fdc_controller;
rom_t rom;
} b215_t;
static void
b215_close(void *priv)
{
b215_t *dev = (b215_t *)priv;
free(dev);
}
static void *
b215_init(const device_t *info)
{
b215_t *dev = (b215_t *)malloc(sizeof(b215_t));
memset(dev, 0, sizeof(b215_t));
rom_init(&dev->rom, ROM_B215, ROM_ADDR, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
device_add(&fdc_at_device);
return dev;
}
static int b215_available(void)
{
return rom_present(ROM_B215);
}
static const device_config_t b215_config[] = {
{
"bios_addr", "BIOS Address:", CONFIG_HEX20, "", 0xca000, "", { 0 },
{
{
"CA00H", 0xca000
},
{
"CC00H", 0xcc000
},
{
""
}
}
},
{
"", "", -1
}
};
const device_t fdc_b215_device = {
"Magitronic B215",
DEVICE_ISA,
0,
b215_init,
b215_close,
NULL,
{b215_available},
NULL,
NULL,
b215_config};

View File

@@ -1,55 +1,63 @@
/*
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the VARCem Project.
*
* Implementation of the DTK PII-151B and PII-158B cards.
* Implementation of the DTK MiniMicro series of Floppy Disk Controllers.
* Original code from VARCem. Fully rewritten, fixed and improved for 86Box.
*
* These are DP8473-based floppy controller ISA cards for XT
* class systems, and allow usage of standard and high-density
* drives on them. They have their own BIOS which takes over
* from the standard system BIOS.
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
* Author: Fred N. van Kempen, <decwiz@yahoo.com>,
* Tiseno100
*
* Copyright 2019 Fred N. van Kempen.
* Copyright 2021 Tiseno100
*
* Redistribution and use in source and binary forms, with
* or without modification, are permitted provided that the
* Redistribution and use in source and binary forms, with
* or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the entire
* above notice, this list of conditions and the following
* disclaimer.
* 1. Redistributions of source code must retain the entire
* above notice, this list of conditions and the following
* disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names
* of its contributors may be used to endorse or promote
* products derived from this software without specific
* prior written permission.
* 3. Neither the name of the copyright holder nor the names
* of its contributors may be used to endorse or promote
* products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _GNU_SOURCE
/*
Notes:
VARCem uses the DP8473 for both floppy disk controllers. The statement though is wrong.
MiniMicro 4 uses a Zilog Z0765A08PSC(Clone of the NEC 765)
MiniMicro 1 uses a National Semiconductor DP8473(Clone of the NEC 765 with additional NSC commands)
Issues:
MiniMicro 4 WON'T WORK with XT machines. This statement has to be confirmed by someone with the real card itself.
MiniMicro 4 also won't work with the XT FDC which the Zilog claims to be.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -61,57 +69,23 @@
#include <86box/device.h>
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/pic.h>
#include <86box/rom.h>
#include <86box/machine.h>
#include <86box/timer.h>
#include <86box/plat.h>
#include <86box/ui.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#define ROM_PII_151B L"roms/floppy/dtk/pii-151b.rom"
#define ROM_PII_158B L"roms/floppy/dtk/pii-158b.rom"
#define DTK_VARIANT ((info->local == 158) ? ROM_PII_158B : ROM_PII_151B)
#define DTK_CHIP ((info->local == 158) ? &fdc_at_device : &fdc_dp8473_device)
#define BIOS_ADDR (uint32_t)(device_get_config_hex20("bios_addr") & 0x000fffff)
#define ROM_PII_151B L"roms/floppy/dtk/pii-151b.rom"
#define ROM_PII_158B L"roms/floppy/dtk/pii-158b.rom"
typedef struct {
const char *name;
int type;
uint32_t bios_addr,
bios_size;
rom_t bios_rom;
fdc_t *fdc;
} pii_t;
/* Load and enable a BIOS ROM if we have one, and is enabled. */
static void
set_bios(pii_t *dev, wchar_t *fn)
typedef struct
{
uint32_t temp;
FILE *fp;
/* Only do this if needed. */
if ((fn == NULL) || (dev->bios_addr == 0)) return;
if ((fp = rom_fopen(fn, L"rb")) == NULL) return;
(void)fseek(fp, 0L, SEEK_END);
temp = ftell(fp);
(void)fclose(fp);
/* Assume 128K, then go down. */
dev->bios_size = 0x020000;
while (temp < dev->bios_size)
dev->bios_size >>= 1;
/* Create a memory mapping for the space. */
rom_init(&dev->bios_rom, fn, dev->bios_addr,
dev->bios_size, dev->bios_size-1, 0, MEM_MAPPING_EXTERNAL);
}
rom_t bios_rom;
} pii_t;
static void
pii_close(void *priv)
@@ -121,36 +95,20 @@ pii_close(void *priv)
free(dev);
}
static void *
pii_init(const device_t *info)
{
pii_t *dev;
dev = (pii_t *)malloc(sizeof(pii_t));
memset(dev, 0x00, sizeof(pii_t));
dev->type = info->local;
memset(dev, 0, sizeof(pii_t));
dev->bios_addr = device_get_config_hex20("bios_addr");
if (BIOS_ADDR != 0)
rom_init(&dev->bios_rom, DTK_VARIANT, BIOS_ADDR, 0x2000, 0x1ffff, 0, MEM_MAPPING_EXTERNAL);
if (dev->bios_addr != 0x000000) {
switch (dev->type) {
case 151:
set_bios(dev, ROM_PII_151B);
break;
case 158:
set_bios(dev, ROM_PII_158B);
break;
}
}
device_add(DTK_CHIP);
/* Attach the DP8473 chip. */
dev->fdc = device_add(&fdc_at_device);
//pclog("FDC: %s (I/O=%04X, flags=%08x)\n",
// info->name, dev->fdc->base_address, dev->fdc->flags);
return(dev);
return dev;
}
static int pii_151b_available(void)
@@ -165,19 +123,19 @@ static int pii_158_available(void)
static const device_config_t pii_config[] = {
{
"bios_addr", "BIOS address", CONFIG_HEX20, "", 0x0ce000, "", { 0 },
"bios_addr", "BIOS Address:", CONFIG_HEX20, "", 0xce000, "", { 0 },
{
{
"Disabled", 0
},
{
"CA00H", 0x0ca000
"CA00H", 0xca000
},
{
"CC00H", 0x0cc000
"CC00H", 0xcc000
},
{
"CE00H", 0x0ce000
"CE00H", 0xce000
},
{
""
@@ -193,16 +151,22 @@ const device_t fdc_pii151b_device = {
"DTK PII-151B (MiniMicro) Floppy Drive Controller",
DEVICE_ISA,
151,
pii_init, pii_close, NULL,
{ pii_151b_available }, NULL, NULL,
pii_config
};
pii_init,
pii_close,
NULL,
{pii_151b_available},
NULL,
NULL,
pii_config};
const device_t fdc_pii158b_device = {
"DTK PII-158B (MiniMicro4) Floppy Drive Controller",
DEVICE_ISA,
158,
pii_init, pii_close, NULL,
{ pii_158_available }, NULL, NULL,
pii_config
};
pii_init,
pii_close,
NULL,
{pii_158_available},
NULL,
NULL,
pii_config};

View File

@@ -146,6 +146,5 @@ extern const device_t wd76c10_device;
/* Miscellaneous Hardware */
extern const device_t phoenix_486_jumper_device;
extern const device_t vpc2007_device;
extern const device_t olivetti_m290_registers_device;
#endif /*EMU_CHIPSET_H*/

View File

@@ -34,7 +34,6 @@ extern int fdc_type;
#define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */
#define FDC_FLAG_TOSHIBA 0x100 /* T1000, T1200 */
#define FDC_FLAG_AMSTRAD 0x200 /* Non-AT Amstrad machines */
#define FDC_FLAG_NSDP 0x400 /* DP8473N, DP8473V */
typedef struct {

View File

@@ -27,6 +27,7 @@ extern int fdc_type;
/* Controller types. */
#define FDC_INTERNAL 0
extern const device_t fdc_b215_device;
extern const device_t fdc_pii151b_device;
extern const device_t fdc_pii158b_device;

View File

@@ -278,8 +278,6 @@ extern const device_t *at_flytech386_get_device(void);
extern const device_t *at_commodore_sl386sx25_get_device(void);
extern const device_t *at_spc4620p_get_device(void);
extern const device_t *at_spc6033p_get_device(void);
extern const device_t *at_ncr3302_get_device(void);
extern const device_t *at_m300_08_get_device(void);
#endif
/* m_at_386dx_486.c */

View File

@@ -271,7 +271,7 @@ g_strv_length(gchar **str_array)
#define g_rand_free free
#define g_realloc realloc
#define g_snprintf snprintf
#define g_strdup strdup
#define g_strdup(str) str ? strdup(str) : NULL
#define g_strerror strerror
#define g_strfreev free
#define g_string_append_printf sprintf /* unimplemented */

View File

@@ -35,7 +35,6 @@
#include <86box/rom.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/hdc.h>
#include <86box/sio.h>
#include <86box/serial.h>
@@ -476,7 +475,7 @@ machine_at_wd76c10_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_ide_init(model);
machine_at_common_init(model);
device_add(&keyboard_ps2_quadtel_device);
@@ -673,9 +672,50 @@ machine_at_pja511m_init(const machine_t *model)
}
#endif
static uint8_t
m290_read(uint16_t port, void *priv)
{
uint8_t ret = 0x0;
switch (port) {
/*
* port 69:
* dip-switch bank on mainboard (off=1)
* bit 3 - use OCG/CGA display adapter (off) / other display adapter (on)
*/
case 0x69:
if(video_is_cga())
ret |= 0x8|0x4;
ret |= 0x1|0x2;
}
return (ret);
}
int
machine_at_olim290_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/olivetti_m290/m290_pep3_1.25.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&keyboard_at_device);
device_add(&fdc_at_device);
io_sethandler(0x069, 1, m290_read, NULL, NULL, NULL, NULL, NULL, NULL);
return ret;
}
/*
* Current bugs:
* - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error
* - ctrl-alt-del produces an 8042 error
*/
int
machine_at_ncrpc8_init(const machine_t *model)
@@ -691,23 +731,14 @@ machine_at_ncrpc8_init(const machine_t *model)
machine_at_common_init(model);
device_add(&keyboard_at_ncr_device);
mem_remap_top(384);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&fdc_at_device);
return ret;
}
const device_t *
at_ncr3302_get_device(void)
{
return &paradise_pvga1a_ncr3302_device;
}
/*
* Current bugs:
* - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error
* - ctrl-alt-del produces an 8042 error
*/
int
machine_at_ncr3302_init(const machine_t *model)
@@ -728,12 +759,10 @@ machine_at_ncr3302_init(const machine_t *model)
machine_at_common_ide_init(model);
device_add(&neat_device);
device_add(&keyboard_at_ncr_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&fdc_at_device);
if (gfxcard == VID_INTERNAL)
device_add(&paradise_pvga1a_ncr3302_device);
device_add(&paradise_pvga1a_device);
return ret;
}

View File

@@ -71,7 +71,7 @@ const machine_t machines[] = {
{ "[8088] Juko XT clone", "jukopc", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_jukopc_init, NULL },
{ "[8088] Multitech PC-700", "multitech_pc700", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_multitechpc700_init, NULL },
{ "[8088] NCR PC4i", "ncr_pc4i", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 256, 0, machine_xt_ncrpc4i_init, NULL },
{ "[8088] Olivetti M19", "olivetti_m19", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 7159092, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 256, 640, 256, 0, machine_xt_olim19_init, NULL },
{ "[8088] Olivetti M19", "olivetti_m19", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 256, 640, 256, 0, machine_xt_olim19_init, NULL },
{ "[8088] OpenXT", "open_xt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_open_xt_init, NULL },
{ "[8088] Philips P3105/NMS9100", "philips_p3105", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_XTA, 256, 768, 128, 0, machine_xt_p3105_init, NULL },
{ "[8088] Phoenix XT clone", "pxxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_pxxt_init, NULL },
@@ -132,7 +132,7 @@ const machine_t machines[] = {
{ "[GC103] Quadtel 286 clone", "quadt286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_quadt286_init, NULL },
{ "[GC103] Trigem 286M", "tg286m", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 512, 8192, 128, 127, machine_at_tg286m_init, NULL },
{ "[NEAT] AMI 286 clone", "ami286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL },
{ "[NEAT] NCR 3302", "ncr_3302", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO, 512, 16384, 128, 127, machine_at_ncr3302_init, at_ncr3302_get_device },
{ "[NEAT] NCR 3302", "ncr_3302", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_VIDEO, 512, 16384, 128, 127, machine_at_ncr3302_init, NULL },
{ "[NEAT] Phoenix 286 clone", "px286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_px286_init, NULL },
{ "[SCAT] Award 286 clone", "award286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_award286_init, NULL },
{ "[SCAT] GW-286CT GEAR", "gw286ct", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_gw286ct_init, NULL },

View File

@@ -265,6 +265,7 @@ ati28800k_out(uint16_t addr, uint8_t val, void *p)
}
break;
}
break;
default:
ati28800_out(oldaddr, val, p);
break;

View File

@@ -767,6 +767,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
svga->seqregs[svga->seqaddr] &= 0x0f;
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)
svga->set_reset_disabled = svga->seqregs[7] & 1;
break;
case 0x17:
if (gd54xx_is_5422(svga))
gd543x_recalc_mapping(gd54xx);

View File

@@ -43,6 +43,7 @@ typedef struct ht216_t
rom_t bios_rom;
uint32_t vram_mask;
uint8_t adjust_cursor;
int ext_reg_enable;
int clk_sel;
@@ -52,7 +53,6 @@ typedef struct ht216_t
uint32_t read_banks[2], write_banks[2];
uint8_t bg_latch[8];
uint8_t mw_state, mw_cnt, mw_cpu;
uint8_t ht_regs[256];
} ht216_t;
@@ -155,11 +155,12 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
switch (svga->seqaddr & 0xff) {
case 0x83:
svga->attraddr = val & 0x1f;
svga->attrff = (val & 0x80) ? 1 : 0;
svga->attrff = !!(val & 0x80);
break;
case 0x94:
svga->hwcursor.addr = ((val << 6) | (3 << 14) | ((ht216->ht_regs[0xff] & 0x60) << 11)) << 2;
case 0xff:
svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | (3 << 14) | ((ht216->ht_regs[0xff] & 0x60) << 11)) << 2;
break;
case 0x9c: case 0x9d:
svga->hwcursor.x = ht216->ht_regs[0x9d] | ((ht216->ht_regs[0x9c] & 7) << 8);
@@ -222,10 +223,6 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
svga->fullchange = changeframecount;
svga_recalctimings(svga);
break;
case 0xff:
svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | (3 << 14) | ((val & 0x60) << 11)) << 2;
break;
}
switch (svga->seqaddr & 0xff) {
case 0xc8: case 0xc9: case 0xcf: case 0xe0:
@@ -358,7 +355,6 @@ ht216_remap(ht216_t *ht216)
/*Split bank: two banks used*/
/*Windows 3.1 always touches the misc register when split banks are enabled.*/
if (!(ht216->misc & HT_MISC_PAGE_SEL)) {
//pclog("No page sel\n");
ht216->read_banks[0] = ht216->ht_regs[0xe8] << 12;
ht216->write_banks[0] = ht216->ht_regs[0xe8] << 12;
ht216->read_banks[1] = ht216->ht_regs[0xe9] << 12;
@@ -489,6 +485,7 @@ void
ht216_recalctimings(svga_t *svga)
{
ht216_t *ht216 = (ht216_t *)svga->p;
int high_res_256 = 0;
switch (ht216->clk_sel) {
case 5: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break;
@@ -501,7 +498,17 @@ ht216_recalctimings(svga_t *svga)
svga->interlace = ht216->ht_regs[0xe0] & 1;
if ((svga->bpp == 8) && !svga->lowres) {
if (svga->interlace)
high_res_256 = (svga->htotal * 8) > (svga->vtotal * 4);
else
high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2);
ht216->adjust_cursor = 0;
if ((svga->bpp == 8) && (!svga->lowres || high_res_256)) {
if (high_res_256) {
svga->hdisp /= 2;
ht216->adjust_cursor = 1;
}
svga->render = svga_render_8bpp_highres;
}
}
@@ -510,9 +517,14 @@ ht216_recalctimings(svga_t *svga)
static void
ht216_hwcursor_draw(svga_t *svga, int displine)
{
int x;
ht216_t *ht216 = (ht216_t *)svga->p;
int x, shift = (ht216->adjust_cursor ? 2 : 1);
uint32_t dat[2];
int offset = svga->hwcursor_latch.x + svga->hwcursor_latch.xoff;
int width = (ht216->adjust_cursor ? 16 : 32);
if (ht216->adjust_cursor)
offset >>= 1;
if (svga->interlace && svga->hwcursor_oddeven)
svga->hwcursor_latch.addr += 4;
@@ -526,14 +538,14 @@ ht216_hwcursor_draw(svga_t *svga, int displine)
(svga->vram[svga->hwcursor_latch.addr+128+2] << 8) |
svga->vram[svga->hwcursor_latch.addr+128+3];
for (x = 0; x < 32; x++) {
for (x = 0; x < width; x++) {
if (!(dat[0] & 0x80000000))
((uint32_t *)buffer32->line[displine])[svga->x_add + offset + x] = 0;
if (dat[1] & 0x80000000)
((uint32_t *)buffer32->line[displine])[svga->x_add + offset + x] ^= 0xffffff;
dat[0] <<= 1;
dat[1] <<= 1;
dat[0] <<= shift;
dat[1] <<= shift;
}
svga->hwcursor_latch.addr += 4;
@@ -621,24 +633,18 @@ ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_u
break;
case 0x04:
if (ht216->ht_regs[0xfe] & HT_REG_FE_FBRC) {
if (addr & 4) {
for (i = 0; i < count; i++) {
fg_data[i] = (cpu_dat_unexpanded & (1 << (((addr + i + 4) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb];
pclog("FBRC source select = %02x, frgd = %02x, bkgd = %02x\n", (cpu_dat_unexpanded & (1 << (((addr + i + 4) & 7) ^ 7))), ht216->ht_regs[0xf0], ht216->ht_regs[0xf2]);
}
} else {
for (i = 0; i < count; i++) {
fg_data[i] = (cpu_dat_unexpanded & (1 << (((addr + i) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb];
pclog("FBRC source select = %02x, frgd = %02x, bkgd = %02x\n", (cpu_dat_unexpanded & (1 << (((addr + i) & 7) ^ 7))), ht216->ht_regs[0xf0], ht216->ht_regs[0xf2]);
}
for (i = 0; i < count; i++) {
if (ht216->ht_regs[0xfa] & (1 << i))
fg_data[i] = cpu_dat_unexpanded;
else if (ht216->ht_regs[0xfb] & (1 << i))
fg_data[i] = 0xff - cpu_dat_unexpanded;
}
} else {
if (addr & 4) {
for (i = 0; i < count; i++)
fg_data[i] = (ht216->ht_regs[0xf5] & (1 << (((addr + i + 4) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb];
} else {
for (i = 0; i < count; i++)
fg_data[i] = (ht216->ht_regs[0xf5] & (1 << (((addr + i) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb];
for (i = 0; i < count; i++) {
if (ht216->ht_regs[0xfa] & (1 << i))
fg_data[i] = ht216->ht_regs[0xf5];
else if (ht216->ht_regs[0xfb] & (1 << i))
fg_data[i] = 0xff - ht216->ht_regs[0xf5];
}
}
break;
@@ -819,8 +825,6 @@ ht216_dm_masked_write(ht216_t *ht216, uint32_t addr, uint8_t val, uint8_t bit_ma
svga_t *svga = &ht216->svga;
int writemask2 = svga->writemask;
uint8_t count, i;
uint8_t mask1 = 0;
uint8_t mask2 = 0;
if (svga->adv_flags & FLAG_ADDR_BY8)
writemask2 = svga->seqregs[2];
@@ -856,62 +860,24 @@ ht216_dm_masked_write(ht216_t *ht216, uint32_t addr, uint8_t val, uint8_t bit_ma
count = 4;
if (ht216->mw_cnt == 0) {
mask1 = bit_mask;
ht216->mw_cnt = 1;
} else if (ht216->mw_cnt == 1) {
mask2 = bit_mask;
ht216->mw_cnt = 0;
}
switch (svga->writemode) {
case 0:
if ((bit_mask == 0xff) && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) {
for (i = 0; i < count; i++) {
if (svga->adv_flags & FLAG_ADDR_BY8) {
if (writemask2 & (0x80 >> i))
svga->vram[addr | i] = val;
} else {
if (writemask2 & (1 << i)) {
svga->vram[addr | i] = val;
pclog("BitMask = ff, vram dat = %02x, val = %02x\n", svga->vram[addr | i], val);
}
}
}
return;
if (bit_mask == 0xff) {
for (i = 0; i < count; i++) {
if (writemask2 & (1 << i)) {
svga->vram[addr | i] = val;
}
break;
case 2:
if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) {
for (i = 0; i < count; i++) {
if (svga->adv_flags & FLAG_ADDR_BY8) {
if (writemask2 & (0x80 >> i))
svga->vram[addr | i] = (val & bit_mask) | (svga->vram[addr | i] & ~bit_mask);
} else {
if (writemask2 & (1 << i))
svga->vram[addr | i] = (val & bit_mask) | (svga->vram[addr | i] & ~bit_mask);
}
}
return;
}
break;
}
switch (svga->gdcreg[3] & 0x18) {
case 0x00: /* Set */
}
} else {
if (writemask2 == 0x0f) {
for (i = 0; i < count; i++) {
if (svga->adv_flags & FLAG_ADDR_BY8) {
if (writemask2 & (0x80 >> i))
svga->vram[addr | i] = (val & bit_mask) | (svga->vram[addr | i] & ~bit_mask);
} else {
if (writemask2 & (1 << i)) {
svga->vram[addr | i] = (val & bit_mask) | (svga->vram[addr | i] & ~bit_mask);
pclog("BitMask = %02x, vram dat = %02x, actual val = %02x, addr = %05x, first = %02x, second = %02x\n", bit_mask, svga->vram[addr | i], val, addr | i, mask1, mask2);
}
svga->vram[addr | i] = (svga->latch.b[i] & bit_mask) | (svga->vram[addr | i] & ~bit_mask);
}
} else {
for (i = 0; i < count; i++) {
if (writemask2 & (1 << i)) {
svga->vram[addr | i] = (val & bit_mask) | (svga->vram[addr | i] & ~bit_mask);
}
}
break;
}
}
}
@@ -978,13 +944,7 @@ ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val)
}
} else if (ht216->ht_regs[0xf3]) {
if (ht216->ht_regs[0xf3] & 2) {
if (ht216->mw_state == 0) {
ht216->mw_cpu = val;
ht216->mw_state = 1;
} else if (ht216->mw_state == 1) {
ht216_dm_masked_write(ht216, addr, val, ht216->mw_cpu);
ht216->mw_state = 0;
}
ht216_dm_masked_write(ht216, addr, val, val);
} else
ht216_dm_masked_write(ht216, addr, val, ht216->ht_regs[0xf4]);
} else {
@@ -992,8 +952,9 @@ ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val)
addr = (addr << 3) & 0xfffff;
for (i = 0; i < 8; i++)
ht216_dm_write(ht216, addr + i, (val & (0x80 >> i)) ? 0xff : 0, val);
} else
} else {
ht216_dm_write(ht216, addr, val, val);
}
}
}
@@ -1023,7 +984,7 @@ ht216_writew(uint32_t addr, uint16_t val, void *p)
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1];
if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe])
if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe] && !ht216->ht_regs[0xf3])
svga_writew_linear(addr, val, svga);
else {
ht216_write_common(ht216, addr, val);
@@ -1041,7 +1002,7 @@ ht216_writel(uint32_t addr, uint32_t val, void *p)
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1];
if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe])
if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe] && !ht216->ht_regs[0xf3])
svga_writel_linear(addr, val, svga);
else {
ht216_write_common(ht216, addr, val);

View File

@@ -1071,6 +1071,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
}
break;
}
break;
case SST_nccTable0_I2:
if (!(val & (1 << 31)))
{
@@ -1086,6 +1087,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
}
break;
}
break;
case SST_nccTable0_Q0:
if (!(val & (1 << 31)))
{
@@ -1101,6 +1103,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
}
break;
}
break;
case SST_nccTable0_Q2:
if (!(val & (1 << 31)))
{
@@ -1147,6 +1150,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
}
break;
}
break;
case SST_nccTable0_I3:
if (!(val & (1 << 31)))
{
@@ -1162,6 +1166,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
}
break;
}
break;
case SST_nccTable0_Q1:
if (!(val & (1 << 31)))
{
@@ -1177,6 +1182,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
}
break;
}
break;
case SST_nccTable0_Q3:
if (!(val & (1 << 31)))
{

View File

@@ -660,7 +660,7 @@ SIOOBJ := sio_acc3221.o \
sio_um8669f.o \
sio_vt82c686.o
FDDOBJ := fdd.o fdc.o fdc_pii15xb.o \
FDDOBJ := fdd.o fdc.o fdc_magitronic.o fdc_pii15xb.o \
fdi2raw.o \
fdd_common.o fdd_86f.o \
fdd_fdi.o fdd_imd.o fdd_img.o fdd_json.o \