mirror of
https://github.com/86Box/86Box.git
synced 2025-01-23 17:52:01 -05:00
Merge branch '86Box:master' into master
This commit is contained in:
commit
a387303630
32 changed files with 2027 additions and 611 deletions
5
.github/workflows/cmake.yml
vendored
5
.github/workflows/cmake.yml
vendored
|
@ -37,10 +37,13 @@ jobs:
|
|||
build:
|
||||
- name: Regular
|
||||
preset: regular
|
||||
target: install/strip
|
||||
- name: Debug
|
||||
preset: debug
|
||||
target: install
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
target: install
|
||||
environment:
|
||||
- msystem: MINGW32
|
||||
prefix: mingw-w64-i686
|
||||
|
@ -74,7 +77,7 @@ jobs:
|
|||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D VNC=OFF
|
||||
- name: Build
|
||||
run: cmake --build build --target install
|
||||
run: cmake --build build --target ${{ matrix.build.target }}
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: '86Box-${{ matrix.build.name }}-MSYS2-${{ matrix.environment.msystem }}-${{ github.sha }}'
|
||||
|
|
|
@ -39,7 +39,7 @@ include(CPack)
|
|||
include(CMakeDependentOption)
|
||||
|
||||
add_compile_definitions(CMAKE)
|
||||
add_compile_definitions("$<$<CONFIG:DEBUG>:DEBUG>")
|
||||
add_compile_definitions("$<$<CONFIG:Debug>:DEBUG>")
|
||||
|
||||
if(WIN32)
|
||||
# Disables *_s function warnings
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
"CMAKE_C_FLAGS_OPTIMIZED": "-march=native -mtune=native -O3 -ffp-contract=last -flto",
|
||||
"CMAKE_CXX_FLAGS_OPTIMIZED": "-march=native -mtune=native -O3 -ffp-contract=last -flto"
|
||||
},
|
||||
"hidden": true
|
||||
"hidden": true,
|
||||
"binaryDir": "build"
|
||||
},
|
||||
{
|
||||
"name": "regular",
|
||||
|
@ -70,4 +71,4 @@
|
|||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
156
src/86box.c
156
src/86box.c
|
@ -26,6 +26,13 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <wchar.h>
|
||||
#ifdef __APPLE__
|
||||
#include <string.h>
|
||||
#include <dispatch/dispatch.h>
|
||||
#ifdef __aarch64__
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
|
@ -109,6 +116,7 @@ int confirm_exit_cmdl = 1; /* (O) do not ask for confirmation on quit if set t
|
|||
uint64_t unique_id = 0;
|
||||
uint64_t source_hwnd = 0;
|
||||
#endif
|
||||
char rom_path[1024] = { '\0'}; /* (O) full path to ROMs */
|
||||
char log_path[1024] = { '\0'}; /* (O) full path of logfile */
|
||||
char vm_name[1024] = { '\0'}; /* (O) display name of the VM */
|
||||
|
||||
|
@ -379,12 +387,13 @@ pc_log(const char *fmt, ...)
|
|||
int
|
||||
pc_init(int argc, char *argv[])
|
||||
{
|
||||
char path[2048];
|
||||
char path[2048], path2[2048];
|
||||
char *cfg = NULL, *p;
|
||||
char temp[128];
|
||||
struct tm *info;
|
||||
time_t now;
|
||||
int c;
|
||||
int c, vmrp = 0;
|
||||
int ng = 0, lvmp = 0;
|
||||
uint32_t *uid, *shwnd;
|
||||
|
||||
/* Grab the executable's full path. */
|
||||
|
@ -401,7 +410,10 @@ pc_init(int argc, char *argv[])
|
|||
* could have been set to something else.
|
||||
*/
|
||||
plat_getcwd(usr_path, sizeof(usr_path) - 1);
|
||||
plat_getcwd(rom_path, sizeof(rom_path) - 1);
|
||||
|
||||
memset(path, 0x00, sizeof(path));
|
||||
memset(path2, 0x00, sizeof(path));
|
||||
|
||||
for (c=1; c<argc; c++) {
|
||||
if (argv[c][0] != '-') break;
|
||||
|
@ -411,30 +423,49 @@ usage:
|
|||
printf("\nUsage: 86box [options] [cfg-file]\n\n");
|
||||
printf("Valid options are:\n\n");
|
||||
printf("-? or --help - show this information\n");
|
||||
printf("-C or --dumpcfg - dump config file after loading\n");
|
||||
#ifdef _WIN32
|
||||
printf("-A or --crashdump - enables crashdump on exception\n");
|
||||
#endif
|
||||
printf("-C or --config path - set 'path' to be config file\n");
|
||||
#ifdef _WIN32
|
||||
printf("-D or --debug - force debug output logging\n");
|
||||
printf("-E or --nographic - forces the old behavior\n");
|
||||
#endif
|
||||
printf("-F or --fullscreen - start in fullscreen mode\n");
|
||||
printf("-L or --logfile path - set 'path' to be the logfile\n");
|
||||
printf("-P or --vmpath path - set 'path' to be root for vm\n");
|
||||
printf("-V or --vmname name - overrides the name of the running VM.\n");
|
||||
printf("-S or --settings - show only the settings dialog\n");
|
||||
printf("-N or --noconfirm - do not ask for confirmation on quit\n");
|
||||
#ifdef _WIN32
|
||||
printf("-H or --hwnd id,hwnd - sends back the main dialog's hwnd\n");
|
||||
#endif
|
||||
printf("-R or --crashdump - enables crashdump on exception\n");
|
||||
printf("-L or --logfile path - set 'path' to be the logfile\n");
|
||||
printf("-M or --vmrompath - ROM path is roms subdirectory inside the userfiles path\n");
|
||||
printf("-N or --noconfirm - do not ask for confirmation on quit\n");
|
||||
printf("-O or --dumpcfg - dump config file after loading\n");
|
||||
printf("-P or --vmpath path - set 'path' to be root for vm\n");
|
||||
printf("-R or --rompath path - set 'path' to be ROM path\n");
|
||||
printf("-S or --settings - show only the settings dialog\n");
|
||||
printf("-V or --vmname name - overrides the name of the running VM\n");
|
||||
printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n");
|
||||
printf("\nA config file can be specified. If none is, the default file will be used.\n");
|
||||
return(0);
|
||||
} else if (!strcasecmp(argv[c], "--vmrompath") ||
|
||||
!strcasecmp(argv[c], "-M")) {
|
||||
vmrp = 1;
|
||||
} else if (!strcasecmp(argv[c], "--lastvmpath") ||
|
||||
!strcasecmp(argv[c], "-Z")) {
|
||||
lvmp = 1;
|
||||
} else if (!strcasecmp(argv[c], "--dumpcfg") ||
|
||||
!strcasecmp(argv[c], "-C")) {
|
||||
!strcasecmp(argv[c], "-O")) {
|
||||
do_dump_config = 1;
|
||||
#ifdef _WIN32
|
||||
} else if (!strcasecmp(argv[c], "--debug") ||
|
||||
!strcasecmp(argv[c], "-D")) {
|
||||
force_debug = 1;
|
||||
#endif
|
||||
} else if (!strcasecmp(argv[c], "--nographic") ||
|
||||
!strcasecmp(argv[c], "-E")) {
|
||||
/* Currently does nothing, but if/when we implement a built-in manager,
|
||||
it's going to force the manager not to run, allowing the old usage
|
||||
without parameter. */
|
||||
ng = 1;
|
||||
} else if (!strcasecmp(argv[c], "--fullscreen") ||
|
||||
!strcasecmp(argv[c], "-F")) {
|
||||
start_in_fullscreen = 1;
|
||||
|
@ -448,6 +479,16 @@ usage:
|
|||
if ((c+1) == argc) goto usage;
|
||||
|
||||
strcpy(path, argv[++c]);
|
||||
} else if (!strcasecmp(argv[c], "--rompath") ||
|
||||
!strcasecmp(argv[c], "-R")) {
|
||||
if ((c+1) == argc) goto usage;
|
||||
|
||||
strcpy(path2, argv[++c]);
|
||||
} else if (!strcasecmp(argv[c], "--config") ||
|
||||
!strcasecmp(argv[c], "-C")) {
|
||||
if ((c+1) == argc) goto usage;
|
||||
|
||||
cfg = argv[++c];
|
||||
} else if (!strcasecmp(argv[c], "--vmname") ||
|
||||
!strcasecmp(argv[c], "-V")) {
|
||||
if ((c+1) == argc) goto usage;
|
||||
|
@ -459,10 +500,10 @@ usage:
|
|||
} else if (!strcasecmp(argv[c], "--noconfirm") ||
|
||||
!strcasecmp(argv[c], "-N")) {
|
||||
confirm_exit_cmdl = 0;
|
||||
} else if (!strcasecmp(argv[c], "--crashdump") ||
|
||||
!strcasecmp(argv[c], "-R")) {
|
||||
enable_crashdump = 1;
|
||||
#ifdef _WIN32
|
||||
} else if (!strcasecmp(argv[c], "--crashdump") ||
|
||||
!strcasecmp(argv[c], "-A")) {
|
||||
enable_crashdump = 1;
|
||||
} else if (!strcasecmp(argv[c], "--hwnd") ||
|
||||
!strcasecmp(argv[c], "-H")) {
|
||||
|
||||
|
@ -484,18 +525,25 @@ usage:
|
|||
}
|
||||
|
||||
/* One argument (config file) allowed. */
|
||||
if (c < argc)
|
||||
cfg = argv[c++];
|
||||
if (c < argc) {
|
||||
if (lvmp)
|
||||
strcpy(path, argv[c++]);
|
||||
else
|
||||
cfg = argv[c++];
|
||||
}
|
||||
|
||||
if (c != argc) goto usage;
|
||||
|
||||
plat_path_slash(usr_path);
|
||||
plat_path_slash(rom_path);
|
||||
|
||||
/*
|
||||
* If the user provided a path for files, use that
|
||||
* instead of the current working directory. We do
|
||||
* make sure that if that was a relative path, we
|
||||
* make it absolute.
|
||||
*/
|
||||
if (path[0] != L'\0') {
|
||||
if (path[0] != '\0') {
|
||||
if (! plat_path_abs(path)) {
|
||||
/*
|
||||
* This looks like a relative path.
|
||||
|
@ -503,7 +551,6 @@ usage:
|
|||
* Add it to the current working directory
|
||||
* to convert it (back) to an absolute path.
|
||||
*/
|
||||
plat_path_slash(usr_path);
|
||||
strcat(usr_path, path);
|
||||
} else {
|
||||
/*
|
||||
|
@ -519,6 +566,43 @@ usage:
|
|||
plat_dir_create(usr_path);
|
||||
}
|
||||
|
||||
if (vmrp && (path2[0] == '\0')) {
|
||||
strcpy(path2, usr_path);
|
||||
plat_path_slash(path2);
|
||||
strcat(path2, "roms");
|
||||
plat_path_slash(path2);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user provided a path for ROMs, use that
|
||||
* instead of the current working directory. We do
|
||||
* make sure that if that was a relative path, we
|
||||
* make it absolute.
|
||||
*/
|
||||
if (path2[0] != '\0') {
|
||||
if (! plat_path_abs(path2)) {
|
||||
/*
|
||||
* This looks like a relative path.
|
||||
*
|
||||
* Add it to the current working directory
|
||||
* to convert it (back) to an absolute path.
|
||||
*/
|
||||
strcat(rom_path, path2);
|
||||
} else {
|
||||
/*
|
||||
* The user-provided path seems like an
|
||||
* absolute path, so just use that.
|
||||
*/
|
||||
strcpy(rom_path, path2);
|
||||
}
|
||||
|
||||
/* If the specified path does not yet exist,
|
||||
create it. */
|
||||
if (! plat_dir_check(rom_path))
|
||||
plat_dir_create(rom_path);
|
||||
} else
|
||||
rom_path[0] = '\0';
|
||||
|
||||
/* Grab the name of the configuration file. */
|
||||
if (cfg == NULL)
|
||||
cfg = CONFIG_FILE;
|
||||
|
@ -554,19 +638,20 @@ usage:
|
|||
|
||||
/* Make sure we have a trailing backslash. */
|
||||
plat_path_slash(usr_path);
|
||||
if (rom_path[0] != '\0')
|
||||
plat_path_slash(rom_path);
|
||||
|
||||
/* At this point, we can safely create the full path name. */
|
||||
plat_append_filename(cfg_path, usr_path, p);
|
||||
|
||||
/*
|
||||
* Get the current directory's name
|
||||
* Get the current directory's name
|
||||
*
|
||||
* At this point usr_path is perfectly initialized.
|
||||
* If no --vmname parameter specified we'll use the
|
||||
* working directory name as the VM's name.
|
||||
*/
|
||||
if (strlen(vm_name) == 0)
|
||||
{
|
||||
if (strlen(vm_name) == 0) {
|
||||
char ltemp[1024] = { '\0'};
|
||||
plat_get_dirname(ltemp, usr_path);
|
||||
strcpy(vm_name, plat_get_filename(ltemp));
|
||||
|
@ -581,15 +666,14 @@ usage:
|
|||
strftime(temp, sizeof(temp), "%Y/%m/%d %H:%M:%S", info);
|
||||
pclog("#\n# %ls v%ls logfile, created %s\n#\n",
|
||||
EMU_NAME_W, EMU_VERSION_W, temp);
|
||||
#ifdef _WIN32
|
||||
pclog("# Emulator path: %ls\n", exe_path);
|
||||
pclog("# Userfiles path: %ls\n", usr_path);
|
||||
pclog("# Configuration file: %ls\n#\n\n", cfg_path);
|
||||
#else
|
||||
pclog("# VM: %s\n#\n", vm_name);
|
||||
pclog("# Emulator path: %s\n", exe_path);
|
||||
pclog("# Userfiles path: %s\n", usr_path);
|
||||
if (rom_path[0] != '\0')
|
||||
pclog("# ROM path: %s\n", rom_path);
|
||||
else
|
||||
pclog("# ROM path: %sroms\\\n", exe_path);
|
||||
pclog("# Configuration file: %s\n#\n\n", cfg_path);
|
||||
#endif
|
||||
/*
|
||||
* We are about to read the configuration file, which MAY
|
||||
* put data into global variables (the hard- and floppy
|
||||
|
@ -703,7 +787,13 @@ pc_init_modules(void)
|
|||
mem_init();
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
#if defined(__APPLE__) && defined(__aarch64__)
|
||||
pthread_jit_write_protect_np(0);
|
||||
#endif
|
||||
codegen_init();
|
||||
#if defined(__APPLE__) && defined(__aarch64__)
|
||||
pthread_jit_write_protect_np(1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
keyboard_init();
|
||||
|
@ -999,6 +1089,15 @@ pc_close(thread_t *ptr)
|
|||
}
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
static void _ui_window_title(void *s)
|
||||
{
|
||||
ui_window_title((const wchar_t *) s);
|
||||
free(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
pc_run(void)
|
||||
{
|
||||
|
@ -1027,7 +1126,12 @@ pc_run(void)
|
|||
|
||||
if (title_update) {
|
||||
swprintf(temp, sizeof_w(temp), mouse_msg[!!mouse_capture], fps);
|
||||
#ifdef __APPLE__
|
||||
/* Needed due to modifying the UI on the non-main thread is a big no-no. */
|
||||
dispatch_async_f(dispatch_get_main_queue(), wcsdup((const wchar_t *) temp), _ui_window_title);
|
||||
#else
|
||||
ui_window_title(temp);
|
||||
#endif
|
||||
title_update = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,22 +47,7 @@ endif()
|
|||
target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom zip mo hdd
|
||||
net print scsi sio snd vid voodoo plat ui)
|
||||
|
||||
find_package(Freetype REQUIRED)
|
||||
include_directories(${FREETYPE_INCLUDE_DIRS})
|
||||
|
||||
find_package(OpenAL REQUIRED)
|
||||
include_directories(${OPENAL_INCLUDE_DIR})
|
||||
target_link_libraries(86Box ${OPENAL_LIBRARY})
|
||||
|
||||
find_package(SDL2 CONFIG REQUIRED)
|
||||
include_directories(${SDL2_INCLUDE_DIRS})
|
||||
target_link_libraries(86Box SDL2::SDL2)
|
||||
|
||||
find_package(PNG REQUIRED)
|
||||
include_directories(${PNG_INCLUDE_DIRS})
|
||||
target_link_libraries(86Box PNG::PNG)
|
||||
|
||||
if(ARCH STREQUAL "i386")
|
||||
if(WIN32 AND ARCH STREQUAL "i386")
|
||||
if(MSVC)
|
||||
target_link_options(86Box PRIVATE "/LARGEADDRESSAWARE")
|
||||
else()
|
||||
|
@ -70,10 +55,30 @@ if(ARCH STREQUAL "i386")
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT MSVC AND NOT UNIX AND NOT APPLE)
|
||||
if(MINGW)
|
||||
target_link_options(86Box PRIVATE "-static")
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".dll.a")
|
||||
endif()
|
||||
|
||||
find_package(Freetype REQUIRED)
|
||||
include_directories(${FREETYPE_INCLUDE_DIRS})
|
||||
|
||||
find_package(OpenAL REQUIRED)
|
||||
include_directories(${OPENAL_INCLUDE_DIR})
|
||||
target_link_libraries(86Box ${OPENAL_LIBRARY})
|
||||
|
||||
find_package(SDL2 REQUIRED)
|
||||
include_directories(${SDL2_INCLUDE_DIRS})
|
||||
if(MINGW)
|
||||
target_link_libraries(86Box SDL2::SDL2-static)
|
||||
else()
|
||||
target_link_libraries(86Box SDL2::SDL2)
|
||||
endif()
|
||||
|
||||
find_package(PNG REQUIRED)
|
||||
include_directories(${PNG_INCLUDE_DIRS})
|
||||
target_link_libraries(86Box PNG::PNG)
|
||||
|
||||
configure_file(include/86box/version.h.in include/86box/version.h @ONLY)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
|
||||
|
@ -123,7 +128,7 @@ add_subdirectory(sio)
|
|||
add_subdirectory(scsi)
|
||||
add_subdirectory(sound)
|
||||
add_subdirectory(video)
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
if (WIN32)
|
||||
add_subdirectory(win)
|
||||
else()
|
||||
add_subdirectory(unix)
|
||||
|
|
|
@ -238,6 +238,16 @@ cdrom_seek(cdrom_t *dev, uint32_t pos)
|
|||
}
|
||||
|
||||
|
||||
int
|
||||
cdrom_is_pre(cdrom_t *dev, uint32_t lba)
|
||||
{
|
||||
if (dev->ops && dev->ops->is_track_pre)
|
||||
return dev->ops->is_track_pre(dev, lba);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len)
|
||||
{
|
||||
|
|
|
@ -155,12 +155,28 @@ image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf)
|
|||
if (track == -1)
|
||||
return 0;
|
||||
else {
|
||||
cdi_get_audio_track_info(img, 0, cdi_get_track(img, pos), &number, &tmsf, &attr);
|
||||
cdi_get_audio_track_info(img, 0, track, &number, &tmsf, &attr);
|
||||
return attr == AUDIO_TRACK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
image_is_track_pre(cdrom_t *dev, uint32_t lba)
|
||||
{
|
||||
cd_img_t *img = (cd_img_t *)dev->image;
|
||||
int track;
|
||||
|
||||
/* GetTrack requires LBA. */
|
||||
track = cdi_get_track(img, lba);
|
||||
|
||||
if (track != -1)
|
||||
return cdi_get_audio_track_pre(img, track);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
image_sector_size(struct cdrom *dev, uint32_t lba)
|
||||
{
|
||||
|
@ -231,6 +247,7 @@ static const cdrom_ops_t cdrom_image_ops = {
|
|||
image_get_tracks,
|
||||
image_get_track_info,
|
||||
image_get_subchannel,
|
||||
image_is_track_pre,
|
||||
image_sector_size,
|
||||
image_read_sector,
|
||||
image_track_type,
|
||||
|
|
|
@ -272,6 +272,18 @@ cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_
|
|||
}
|
||||
|
||||
|
||||
int
|
||||
cdi_get_audio_track_pre(cd_img_t *cdi, int track)
|
||||
{
|
||||
track_t *trk = &cdi->tracks[track - 1];
|
||||
|
||||
if ((track < 1) || (track > cdi->tracks_num))
|
||||
return 0;
|
||||
|
||||
return trk->pre;
|
||||
}
|
||||
|
||||
|
||||
/* This replaces both Info and EndInfo, they are specified by a variable. */
|
||||
int
|
||||
cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, TMSF *start, uint8_t *attr)
|
||||
|
@ -709,6 +721,25 @@ cdi_cue_get_frame(uint64_t *frames, char **line)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
cdi_cue_get_flags(track_t *cur, char **line)
|
||||
{
|
||||
char temp[128], temp2[128];
|
||||
int success;
|
||||
|
||||
success = cdi_cue_get_buffer(temp, line, 0);
|
||||
if (! success) return 0;
|
||||
|
||||
memset(temp2, 0x00, sizeof(temp2));
|
||||
success = sscanf(temp, "%s", temp2) == 1;
|
||||
if (! success) return 0;
|
||||
|
||||
cur->pre = (strstr(temp2, "PRE") != NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, uint64_t *total_pregap, uint64_t cur_pregap)
|
||||
{
|
||||
|
@ -850,6 +881,8 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
|
|||
trk.form = 0;
|
||||
trk.mode2 = 0;
|
||||
|
||||
trk.pre = 0;
|
||||
|
||||
if (!strcmp(type, "AUDIO")) {
|
||||
trk.sector_size = RAW_SECTOR_SIZE;
|
||||
trk.attr = AUDIO_TRACK;
|
||||
|
@ -964,7 +997,9 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
|
|||
}
|
||||
} else if (!strcmp(command, "PREGAP"))
|
||||
success = cdi_cue_get_frame(&cur_pregap, &line);
|
||||
else if (!strcmp(command, "CATALOG") || !strcmp(command, "CDTEXTFILE") || !strcmp(command, "FLAGS") || !strcmp(command, "ISRC") ||
|
||||
else if (!strcmp(command, "FLAGS"))
|
||||
success = cdi_cue_get_flags(&trk, &line);
|
||||
else if (!strcmp(command, "CATALOG") || !strcmp(command, "CDTEXTFILE") || !strcmp(command, "ISRC") ||
|
||||
!strcmp(command, "PERFORMER") || !strcmp(command, "POSTGAP") || !strcmp(command, "REM") ||
|
||||
!strcmp(command, "SONGWRITER") || !strcmp(command, "TITLE") || !strcmp(command, "")) {
|
||||
/* Ignored commands. */
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <86box/timer.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/port_92.h>
|
||||
|
@ -79,6 +80,7 @@ typedef struct
|
|||
sff8038i_t *bm[2];
|
||||
nvr_t *nvr;
|
||||
int nvr_enabled, slot;
|
||||
ddma_t *ddma;
|
||||
smbus_piix4_t *smbus;
|
||||
usb_t *usb[2];
|
||||
acpi_t *acpi;
|
||||
|
@ -708,6 +710,19 @@ usb_update_io_mapping(pipc_t *dev, int func)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
pipc_ddma_update(pipc_t *dev, int addr)
|
||||
{
|
||||
uint32_t base;
|
||||
|
||||
if (dev->local >= VIA_PIPC_8231)
|
||||
return;
|
||||
|
||||
base = (dev->pci_isa_regs[addr] & 0xf0) | (((uint32_t) dev->pci_isa_regs[addr | 0x01]) << 8);
|
||||
ddma_update_io_mapping(dev->ddma, (addr & 0x0e) >> 1, (dev->pci_isa_regs[addr] & 0xf0), dev->pci_isa_regs[addr | 0x01], (dev->pci_isa_regs[addr] & 0x08) && (base != 0x0000));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pipc_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
|
@ -854,19 +869,13 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
|
|||
|
||||
case 0x60: case 0x62: case 0x64: case 0x66:
|
||||
case 0x6a: case 0x6c: case 0x6e:
|
||||
c = (addr & 0x0e) >> 1;
|
||||
dma[c].ab = (dma[c].ab & 0xffffff0f) | (val & 0xf0);
|
||||
dma[c].ac = (dma[c].ac & 0xffffff0f) | (val & 0xf0);
|
||||
if (val & 0x08)
|
||||
dma_e |= (1 << c);
|
||||
else
|
||||
dma_e &= ~(1 << c);
|
||||
dev->pci_isa_regs[addr] = val & 0xf8;
|
||||
pipc_ddma_update(dev, addr);
|
||||
break;
|
||||
case 0x61: case 0x63: case 0x65: case 0x67:
|
||||
case 0x6b: case 0x6d: case 0x6f:
|
||||
c = (addr & 0x0e) >> 1;
|
||||
dma[c].ab = (dma[c].ab & 0xffff00ff) | (val << 8);
|
||||
dma[c].ac = (dma[c].ac & 0xffff00ff) | (val << 8);
|
||||
dev->pci_isa_regs[addr] = val;
|
||||
pipc_ddma_update(dev, addr & 0xfe);
|
||||
break;
|
||||
|
||||
case 0x70: case 0x71: case 0x72: case 0x73:
|
||||
|
@ -1353,6 +1362,9 @@ pipc_init(const device_t *info)
|
|||
pci_enable_mirq(2);
|
||||
}
|
||||
|
||||
if (dev->local < VIA_PIPC_8231)
|
||||
dev->ddma = device_add(&ddma_device);
|
||||
|
||||
if (dev->acpi) {
|
||||
acpi_set_slot(dev->acpi, dev->slot);
|
||||
acpi_set_nvr(dev->acpi, dev->nvr);
|
||||
|
|
|
@ -2578,12 +2578,12 @@ save_storage_controllers(void)
|
|||
else
|
||||
config_set_int(cat, "cassette_enabled", cassette_enable);
|
||||
|
||||
if (cassette_fname == NULL)
|
||||
if (strlen(cassette_fname) == 0)
|
||||
config_delete_var(cat, "cassette_file");
|
||||
else
|
||||
config_set_string(cat, "cassette_file", cassette_fname);
|
||||
|
||||
if (cassette_mode == NULL)
|
||||
if (strlen(cassette_mode) == 0)
|
||||
config_delete_var(cat, "cassette_mode");
|
||||
else
|
||||
config_set_string(cat, "cassette_mode", cassette_mode);
|
||||
|
|
|
@ -195,10 +195,14 @@ exec386(int cycs)
|
|||
cpu_state.oldpc = cpu_state.pc;
|
||||
x86_int(2);
|
||||
nmi_enable = 0;
|
||||
#ifdef OLD_NMI_BEHAVIOR
|
||||
if (nmi_auto_clear) {
|
||||
nmi_auto_clear = 0;
|
||||
nmi = 0;
|
||||
}
|
||||
#else
|
||||
nmi = 0;
|
||||
#endif
|
||||
} else if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) {
|
||||
vector = picinterrupt();
|
||||
if (vector != -1) {
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(__APPLE__) && defined(__aarch64__)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#ifndef INFINITY
|
||||
|
@ -31,6 +34,9 @@
|
|||
#endif
|
||||
#include "386_common.h"
|
||||
|
||||
#if defined(__APPLE__) && defined(__aarch64__)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
|
@ -797,10 +803,14 @@ exec386_dynarec(int cycs)
|
|||
cpu_state.oldpc = cpu_state.pc;
|
||||
x86_int(2);
|
||||
nmi_enable = 0;
|
||||
#ifdef OLD_NMI_BEHAVIOR
|
||||
if (nmi_auto_clear) {
|
||||
nmi_auto_clear = 0;
|
||||
nmi = 0;
|
||||
}
|
||||
#else
|
||||
nmi = 0;
|
||||
#endif
|
||||
} else if ((cpu_state.flags & I_FLAG) && pic.int_pending) {
|
||||
vector = picinterrupt();
|
||||
if (vector != -1) {
|
||||
|
|
|
@ -968,6 +968,9 @@ check_interrupts(void)
|
|||
if (nmi && nmi_enable && nmi_mask) {
|
||||
nmi_enable = 0;
|
||||
interrupt(2);
|
||||
#ifndef OLD_NMI_BEHAVIOR
|
||||
nmi = 0;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if ((cpu_state.flags & I_FLAG) && pic.int_pending && !noint) {
|
||||
|
|
|
@ -79,6 +79,7 @@ extern int confirm_exit_cmdl; /* (O) do not ask for confirmation on quit if set
|
|||
extern uint64_t unique_id;
|
||||
extern uint64_t source_hwnd;
|
||||
#endif
|
||||
extern char rom_path[1024]; /* (O) full path to ROMs */
|
||||
extern char log_path[1024]; /* (O) full path of logfile */
|
||||
extern char vm_name[1024]; /* (O) display name of the VM */
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ typedef struct {
|
|||
void (*get_tracks)(struct cdrom *dev, int *first, int *last);
|
||||
void (*get_track_info)(struct cdrom *dev, uint32_t track, int end, track_info_t *ti);
|
||||
void (*get_subchannel)(struct cdrom *dev, uint32_t lba, subchannel_t *subc);
|
||||
int (*is_track_pre)(struct cdrom *dev, uint32_t lba);
|
||||
int (*sector_size)(struct cdrom *dev, uint32_t lba);
|
||||
int (*read_sector)(struct cdrom *dev, int type, uint8_t *b, uint32_t lba);
|
||||
int (*track_type)(struct cdrom *dev, uint32_t lba);
|
||||
|
@ -136,6 +137,7 @@ extern cdrom_t cdrom[CDROM_NUM];
|
|||
extern int cdrom_lba_to_msf_accurate(int lba);
|
||||
extern double cdrom_seek_time(cdrom_t *dev);
|
||||
extern void cdrom_stop(cdrom_t *dev);
|
||||
extern int cdrom_is_pre(cdrom_t *dev, uint32_t lba);
|
||||
extern int cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len);
|
||||
extern uint8_t cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf);
|
||||
extern uint8_t cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit);
|
||||
|
|
|
@ -58,7 +58,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
int number, track_number, attr, sector_size,
|
||||
mode2, form;
|
||||
mode2, form, pre, pad;
|
||||
uint64_t start, length,
|
||||
skip;
|
||||
track_file_t *file;
|
||||
|
@ -75,6 +75,7 @@ extern void cdi_close(cd_img_t *cdi);
|
|||
extern int cdi_set_device(cd_img_t *cdi, const char *path);
|
||||
extern int cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out);
|
||||
extern int cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out);
|
||||
extern int cdi_get_audio_track_pre(cd_img_t *cdi, int track);
|
||||
extern int cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, TMSF *start, uint8_t *attr);
|
||||
extern int cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num, uint32_t *start, uint8_t *attr);
|
||||
extern int cdi_get_track(cd_img_t *cdi, uint32_t sector);
|
||||
|
|
|
@ -126,7 +126,7 @@ typedef struct svga_t
|
|||
int override;
|
||||
void *p;
|
||||
|
||||
uint8_t crtc[256], gdcreg[64], attrregs[32], seqregs[256],
|
||||
uint8_t crtc[256], gdcreg[256], attrregs[32], seqregs[256],
|
||||
egapal[16],
|
||||
*vram, *changedvram;
|
||||
|
||||
|
@ -264,6 +264,10 @@ extern float stg_getclock(int clock, void *p);
|
|||
extern void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga);
|
||||
extern uint8_t tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga);
|
||||
|
||||
extern void tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga);
|
||||
extern uint8_t tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga);
|
||||
extern void tvp3026_recalctimings(void *p, svga_t *svga);
|
||||
extern void tvp3026_hwcursor_draw(svga_t *svga, int displine);
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t ati68860_ramdac_device;
|
||||
|
@ -292,4 +296,5 @@ extern const device_t stg_ramdac_device;
|
|||
extern const device_t tkd8001_ramdac_device;
|
||||
extern const device_t tseng_ics5301_ramdac_device;
|
||||
extern const device_t tseng_ics5341_ramdac_device;
|
||||
extern const device_t tvp3026_ramdac_device;
|
||||
#endif
|
||||
|
|
|
@ -325,7 +325,10 @@ extern const device_t s3_diamond_stealth_vram_isa_device;
|
|||
extern const device_t s3_ami_86c924_isa_device;
|
||||
extern const device_t s3_metheus_86c928_isa_device;
|
||||
extern const device_t s3_metheus_86c928_vlb_device;
|
||||
extern const device_t s3_v7mirage_86c801_isa_device;
|
||||
extern const device_t s3_spea_mirage_86c801_isa_device;
|
||||
extern const device_t s3_spea_mirage_86c805_vlb_device;
|
||||
extern const device_t s3_mirocrystal_10sd_805_vlb_device;
|
||||
extern const device_t s3_phoenix_86c801_isa_device;
|
||||
extern const device_t s3_phoenix_86c805_vlb_device;
|
||||
extern const device_t s3_bahamas64_vlb_device;
|
||||
extern const device_t s3_bahamas64_pci_device;
|
||||
|
@ -335,10 +338,10 @@ extern const device_t s3_phoenix_trio32_vlb_device;
|
|||
extern const device_t s3_phoenix_trio32_pci_device;
|
||||
extern const device_t s3_diamond_stealth_se_vlb_device;
|
||||
extern const device_t s3_diamond_stealth_se_pci_device;
|
||||
extern const device_t s3_spea_mirage_p64_vlb_device;
|
||||
extern const device_t s3_phoenix_trio64_vlb_device;
|
||||
extern const device_t s3_phoenix_trio64_onboard_pci_device;
|
||||
extern const device_t s3_phoenix_trio64_pci_device;
|
||||
extern const device_t s3_phoenix_trio64vplus_vlb_device;
|
||||
extern const device_t s3_phoenix_trio64vplus_pci_device;
|
||||
extern const device_t s3_phoenix_trio64vplus_onboard_pci_device;
|
||||
extern const device_t s3_phoenix_vision864_pci_device;
|
||||
|
@ -349,10 +352,11 @@ extern const device_t s3_diamond_stealth64_pci_device;
|
|||
extern const device_t s3_diamond_stealth64_vlb_device;
|
||||
extern const device_t s3_diamond_stealth64_964_pci_device;
|
||||
extern const device_t s3_diamond_stealth64_964_vlb_device;
|
||||
extern const device_t s3_mirovideo_40sv_968_pci_device;
|
||||
extern const device_t s3_mirovideo_40sv_968_vlb_device;
|
||||
extern const device_t s3_spea_mercury_p64v_pci_device;
|
||||
extern const device_t s3_elsa_winner2000_pro_x_964_pci_device;
|
||||
extern const device_t s3_elsa_winner2000_pro_x_964_vlb_device;
|
||||
extern const device_t s3_elsa_winner2000_pro_x_pci_device;
|
||||
extern const device_t s3_elsa_winner2000_pro_x_vlb_device;
|
||||
extern const device_t s3_trio64v2_dx_pci_device;
|
||||
|
||||
/* S3 ViRGE */
|
||||
|
|
|
@ -1643,8 +1643,6 @@ vid_init_200(amstrad_t *ams)
|
|||
memset(vid, 0x00, sizeof(amsvid_t));
|
||||
|
||||
vid->emulation = device_get_config_int("video_emulation");
|
||||
cga_palette = (device_get_config_int("display_type") << 1);
|
||||
ams_inform(vid);
|
||||
|
||||
/* Default to CGA */
|
||||
vid->dipswitches = 0x10;
|
||||
|
@ -1677,6 +1675,9 @@ vid_init_200(amstrad_t *ams)
|
|||
cga_init(cga);
|
||||
mda_init(mda);
|
||||
|
||||
cga_palette = (device_get_config_int("display_type") << 1);
|
||||
ams_inform(vid);
|
||||
|
||||
/* Attribute 8 is white on black (on a real MDA it's black on black) */
|
||||
mda_setcol(0x08, 0, 1, 15);
|
||||
mda_setcol(0x88, 0, 1, 15);
|
||||
|
|
|
@ -62,10 +62,35 @@ FILE *
|
|||
rom_fopen(char *fn, char *mode)
|
||||
{
|
||||
char temp[1024];
|
||||
char *fn2;
|
||||
|
||||
plat_append_filename(temp, exe_path, fn);
|
||||
if ((strstr(fn, "roms/") == fn) || (strstr(fn, "roms\\") == fn)) {
|
||||
/* Relative path */
|
||||
fn2 = (char *) malloc(strlen(fn) + 1);
|
||||
memcpy(fn2, fn, strlen(fn) + 1);
|
||||
|
||||
return(plat_fopen(temp, mode));
|
||||
if (rom_path[0] != '\0') {
|
||||
memset(fn2, 0x00, strlen(fn) + 1);
|
||||
memcpy(fn2, &(fn[5]), strlen(fn) - 4);
|
||||
|
||||
plat_append_filename(temp, rom_path, fn2);
|
||||
} else {
|
||||
/* Make sure to make it a backslash, just in case there's malformed
|
||||
code calling us that assumes Windows. */
|
||||
if (fn2[4] == '\\')
|
||||
fn2[4] = '/';
|
||||
|
||||
plat_append_filename(temp, exe_path, fn2);
|
||||
}
|
||||
|
||||
free(fn2);
|
||||
fn2 = NULL;
|
||||
|
||||
return(plat_fopen(temp, mode));
|
||||
} else {
|
||||
/* Absolute path */
|
||||
return(plat_fopen(fn, mode));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
20
src/pit.c
20
src/pit.c
|
@ -110,20 +110,20 @@ ctr_decrease_count(ctr_t *ctr)
|
|||
{
|
||||
if (ctr->bcd) {
|
||||
ctr->units--;
|
||||
if (ctr->units == 0xff) {
|
||||
ctr->units = 9;
|
||||
if (ctr->units == -1) {
|
||||
ctr->units = -7;
|
||||
ctr->tens--;
|
||||
if (ctr->tens == 0xff) {
|
||||
ctr->tens = 9;
|
||||
if (ctr->tens == -1) {
|
||||
ctr->tens = -7;
|
||||
ctr->hundreds--;
|
||||
if (ctr->hundreds == 0xff) {
|
||||
ctr->hundreds = 9;
|
||||
if (ctr->hundreds == -1) {
|
||||
ctr->hundreds = -7;
|
||||
ctr->thousands--;
|
||||
if (ctr->thousands == 0xff) {
|
||||
ctr->thousands = 9;
|
||||
if (ctr->thousands == -1) {
|
||||
ctr->thousands = -7;
|
||||
ctr->myriads--;
|
||||
if (ctr->myriads == 0xff)
|
||||
ctr->myriads = 0; /* 0 - 1 should wrap around to 9999. */
|
||||
if (ctr->myriads == -1)
|
||||
ctr->myriads = -7; /* 0 - 1 should wrap around to 9999. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -692,7 +692,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv)
|
|||
|
||||
ncr_dev->t128.host_pos = MIN(512, dev->buffer_length);
|
||||
ncr_dev->t128.status |= 0x04;
|
||||
timer_on_auto(&ncr_dev->timer, 0.2);
|
||||
timer_on_auto(&ncr_dev->timer, 0.02);
|
||||
} else {
|
||||
if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) {
|
||||
memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length));
|
||||
|
|
|
@ -212,7 +212,8 @@ sound_cd_clean_buffers(void)
|
|||
static void
|
||||
sound_cd_thread(void *param)
|
||||
{
|
||||
int c, r, i, channel_select[2];
|
||||
uint32_t lba;
|
||||
int c, r, i, pre, channel_select[2];
|
||||
double audio_vol_l, audio_vol_r;
|
||||
double cd_buffer_temp[2] = {0.0, 0.0};
|
||||
|
||||
|
@ -231,9 +232,11 @@ sound_cd_thread(void *param)
|
|||
if ((cdrom[i].bus_type == CDROM_BUS_DISABLED) ||
|
||||
(cdrom[i].cd_status == CD_STATUS_EMPTY))
|
||||
continue;
|
||||
lba = cdrom[i].seek_pos;
|
||||
r = cdrom_audio_callback(&(cdrom[i]), cd_buffer[i], CD_BUFLEN * 2);
|
||||
if (!cdrom[i].bus_type || !cdrom[i].sound_on || !r)
|
||||
continue;
|
||||
pre = cdrom_is_pre(&(cdrom[i]), lba);
|
||||
|
||||
if (cdrom[i].get_volume) {
|
||||
audio_vol_l = (float) (cdrom[i].get_volume(cdrom[i].priv, 0));
|
||||
|
@ -277,6 +280,9 @@ sound_cd_thread(void *param)
|
|||
cd_buffer_temp[0] += ((double) cd_buffer[i][c + 1]); /* Channel 1 => Port 0 */
|
||||
|
||||
cd_buffer_temp[0] *= audio_vol_l; /* Multiply Port 0 by Port 0 volume */
|
||||
|
||||
if (pre)
|
||||
cd_buffer_temp[0] = deemph_iir(0, cd_buffer_temp[0]); /* De-emphasize if necessary */
|
||||
}
|
||||
|
||||
if ((audio_vol_r != 0.0) && (channel_select[1] != 0)) {
|
||||
|
@ -286,6 +292,9 @@ sound_cd_thread(void *param)
|
|||
cd_buffer_temp[1] += ((double) cd_buffer[i][c + 1]); /* Channel 1 => Port 1 */
|
||||
|
||||
cd_buffer_temp[1] *= audio_vol_r; /* Multiply Port 1 by Port 1 volume */
|
||||
|
||||
if (pre)
|
||||
cd_buffer_temp[1] = deemph_iir(1, cd_buffer_temp[1]); /* De-emphasize if necessary */
|
||||
}
|
||||
|
||||
/* Apply sound card CD volume and filters */
|
||||
|
|
|
@ -198,7 +198,8 @@ sdl_destroy_texture(void)
|
|||
void
|
||||
sdl_close(void)
|
||||
{
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
if (sdl_mutex != NULL)
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
|
||||
/* Unregister our renderer! */
|
||||
video_setblit(NULL);
|
||||
|
|
|
@ -24,7 +24,7 @@ add_library(vid OBJECT video.c vid_table.c vid_cga.c vid_cga_comp.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_ogc.c vid_nga.c)
|
||||
vid_sdac_ramdac.c vid_ogc.c vid_nga.c vid_tvp3026_ramdac.c)
|
||||
|
||||
if(MGA)
|
||||
target_compile_definitions(vid PRIVATE USE_MGA)
|
||||
|
|
1234
src/video/vid_s3.c
1234
src/video/vid_s3.c
File diff suppressed because it is too large
Load diff
|
@ -53,7 +53,6 @@ static const VIDEO_CARD
|
|||
video_cards[] = {
|
||||
{ "none", NULL },
|
||||
{ "internal", NULL },
|
||||
{ "ami_s3_924", &s3_ami_86c924_isa_device },
|
||||
{ "egawonder800", &atiega_device },
|
||||
{ "mach64gx_isa", &mach64gx_isa_device },
|
||||
{ "ati28800k", &ati28800k_device },
|
||||
|
@ -79,7 +78,6 @@ video_cards[] = {
|
|||
{ "compaq_cga", &compaq_cga_device },
|
||||
{ "compaq_cga_2", &compaq_cga_2_device },
|
||||
{ "compaq_ega", &cpqega_device },
|
||||
{ "stealthvram_isa", &s3_diamond_stealth_vram_isa_device },
|
||||
{ "ega", &ega_device },
|
||||
{ "g2_gc205", &g2_gc205_device },
|
||||
{ "hercules", &hercules_device },
|
||||
|
@ -90,13 +88,11 @@ video_cards[] = {
|
|||
{ "kasan16vga", &et4000_kasan_isa_device },
|
||||
{ "mda", &mda_device },
|
||||
{ "genius", &genius_device },
|
||||
{ "metheus928_isa", &s3_metheus_86c928_isa_device },
|
||||
{ "nga", &nga_device },
|
||||
{ "ogc", &ogc_device },
|
||||
{ "oti037c", &oti037c_device },
|
||||
{ "oti067", &oti067_device },
|
||||
{ "oti077", &oti077_device },
|
||||
{ "orchid_s3_911", &s3_orchid_86c911_isa_device },
|
||||
{ "pvga1a", ¶dise_pvga1a_device },
|
||||
{ "wd90c11", ¶dise_wd90c11_device },
|
||||
{ "wd90c30", ¶dise_wd90c30_device },
|
||||
|
@ -104,8 +100,13 @@ video_cards[] = {
|
|||
{ "pgc", &pgc_device },
|
||||
{ "radius_isa", &radius_svga_multiview_isa_device },
|
||||
{ "rtg3106", &realtek_rtg3106_device },
|
||||
{ "stealthvram_isa", &s3_diamond_stealth_vram_isa_device },
|
||||
{ "orchid_s3_911", &s3_orchid_86c911_isa_device },
|
||||
{ "ami_s3_924", &s3_ami_86c924_isa_device },
|
||||
{ "metheus928_isa", &s3_metheus_86c928_isa_device },
|
||||
{ "px_86c801_isa", &s3_phoenix_86c801_isa_device },
|
||||
{ "px_s3_v7_801_isa", &s3_spea_mirage_86c801_isa_device },
|
||||
{ "sigma400", &sigma_device },
|
||||
{ "px_s3_v7_801_isa", &s3_v7mirage_86c801_isa_device },
|
||||
{ "tvga8900b", &tvga8900b_device },
|
||||
{ "tvga8900d", &tvga8900d_device },
|
||||
{ "tvga9000b", &tvga9000b_device },
|
||||
|
@ -133,28 +134,30 @@ video_cards[] = {
|
|||
{ "cl_gd5480_pci", &gd5480_pci_device },
|
||||
{ "ctl3d_banshee_pci", &creative_voodoo_banshee_device },
|
||||
{ "stealth32_pci", &et4000w32p_pci_device },
|
||||
{ "stealth64v_pci", &s3_diamond_stealth64_964_pci_device },
|
||||
{ "elsawin2kprox_964_pci", &s3_elsa_winner2000_pro_x_964_pci_device },
|
||||
{ "bahamas64_pci", &s3_bahamas64_pci_device },
|
||||
{ "px_vision864_pci", &s3_phoenix_vision864_pci_device },
|
||||
{ "stealthse_pci", &s3_diamond_stealth_se_pci_device },
|
||||
{ "px_trio32_pci", &s3_phoenix_trio32_pci_device },
|
||||
{ "stealth64d_pci", &s3_diamond_stealth64_pci_device },
|
||||
{ "n9_9fx_pci", &s3_9fx_pci_device },
|
||||
{ "px_trio64_pci", &s3_phoenix_trio64_pci_device },
|
||||
{ "elsawin2kprox_pci", &s3_elsa_winner2000_pro_x_pci_device },
|
||||
{ "mirovideo40sv_pci", &s3_mirovideo_40sv_968_pci_device },
|
||||
{ "spea_mercury64p_pci", &s3_spea_mercury_p64v_pci_device },
|
||||
{ "px_vision868_pci", &s3_phoenix_vision868_pci_device },
|
||||
{ "px_trio64vplus_pci", &s3_phoenix_trio64vplus_pci_device },
|
||||
{ "trio64v2dx_pci", &s3_trio64v2_dx_pci_device },
|
||||
{ "stealth3d_2000_pci", &s3_virge_pci_device },
|
||||
{ "stealth3d_3000_pci", &s3_virge_988_pci_device },
|
||||
{ "stealth64d_pci", &s3_diamond_stealth64_pci_device },
|
||||
{ "stealth64v_pci", &s3_diamond_stealth64_964_pci_device },
|
||||
{ "stealthse_pci", &s3_diamond_stealth_se_pci_device },
|
||||
{ "elsawin2kprox_964_pci", &s3_elsa_winner2000_pro_x_964_pci_device },
|
||||
{ "elsawin2kprox_pci", &s3_elsa_winner2000_pro_x_pci_device },
|
||||
#if defined(DEV_BRANCH) && defined(USE_MGA)
|
||||
{ "mystique", &mystique_device },
|
||||
{ "mystique_220", &mystique_220_device },
|
||||
#endif
|
||||
{ "n9_9fx_pci", &s3_9fx_pci_device },
|
||||
{ "bahamas64_pci", &s3_bahamas64_pci_device },
|
||||
{ "px_vision864_pci", &s3_phoenix_vision864_pci_device },
|
||||
{ "px_vision868_pci", &s3_phoenix_vision868_pci_device },
|
||||
{ "px_trio32_pci", &s3_phoenix_trio32_pci_device },
|
||||
{ "px_trio64_pci", &s3_phoenix_trio64_pci_device },
|
||||
{ "px_trio64vplus_pci", &s3_phoenix_trio64vplus_pci_device },
|
||||
#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X)
|
||||
{ "trio3d2x", &s3_trio3d_2x_pci_device },
|
||||
#endif
|
||||
{ "trio64v2dx_pci", &s3_trio64v2_dx_pci_device },
|
||||
{ "virge325_pci", &s3_virge_325_pci_device },
|
||||
{ "virge375_pci", &s3_virge_375_pci_device },
|
||||
{ "virge375_vbe20_pci", &s3_virge_375_4_pci_device },
|
||||
|
@ -179,21 +182,20 @@ video_cards[] = {
|
|||
{ "cl_gd5430_vlb", &gd5430_vlb_device },
|
||||
{ "stealth3d_2000_vlb", &s3_virge_vlb_device },
|
||||
{ "stealth3d_3000_vlb", &s3_virge_988_vlb_device },
|
||||
{ "stealth64d_vlb", &s3_diamond_stealth64_vlb_device },
|
||||
{ "stealth64v_vlb", &s3_diamond_stealth64_964_vlb_device },
|
||||
{ "stealthse_vlb", &s3_diamond_stealth_se_vlb_device },
|
||||
{ "elsawin2kprox_964_vlb", &s3_elsa_winner2000_pro_x_964_vlb_device },
|
||||
{ "elsawin2kprox_vlb", &s3_elsa_winner2000_pro_x_vlb_device },
|
||||
{ "ht216_32", &ht216_32_standalone_device },
|
||||
{ "metheus928_vlb", &s3_metheus_86c928_vlb_device },
|
||||
{ "n9_9fx_vlb", &s3_9fx_vlb_device },
|
||||
{ "bahamas64_vlb", &s3_bahamas64_vlb_device },
|
||||
{ "mirocrystal10sd_vlb", &s3_mirocrystal_10sd_805_vlb_device },
|
||||
{ "px_86c805_vlb", &s3_phoenix_86c805_vlb_device },
|
||||
{ "stealth64v_vlb", &s3_diamond_stealth64_964_vlb_device },
|
||||
{ "bahamas64_vlb", &s3_bahamas64_vlb_device },
|
||||
{ "px_vision864_vlb", &s3_phoenix_vision864_vlb_device },
|
||||
{ "px_vision868_vlb", &s3_phoenix_vision868_vlb_device },
|
||||
{ "stealthse_vlb", &s3_diamond_stealth_se_vlb_device },
|
||||
{ "px_trio32_vlb", &s3_phoenix_trio32_vlb_device },
|
||||
{ "stealth64d_vlb", &s3_diamond_stealth64_vlb_device },
|
||||
{ "n9_9fx_vlb", &s3_9fx_vlb_device },
|
||||
{ "px_trio64_vlb", &s3_phoenix_trio64_vlb_device },
|
||||
{ "px_trio64vplus_vlb", &s3_phoenix_trio64vplus_vlb_device },
|
||||
{ "spea_miragep64_vlb", &s3_spea_mirage_p64_vlb_device },
|
||||
{ "px_vision868_vlb", &s3_phoenix_vision868_vlb_device },
|
||||
{ "ht216_32", &ht216_32_standalone_device },
|
||||
{ "virge325_vlb", &s3_virge_325_vlb_device },
|
||||
{ "virge375_vlb", &s3_virge_375_vlb_device },
|
||||
{ "virge375_vbe20_vlb", &s3_virge_375_4_vlb_device },
|
||||
|
|
|
@ -115,6 +115,7 @@ typedef struct tgui_t
|
|||
int16_t dst_x, dst_y;
|
||||
int16_t dst_y_clip, dst_x_clip;
|
||||
int16_t size_x, size_y;
|
||||
uint16_t sv_size_y;
|
||||
uint16_t patloc;
|
||||
uint32_t fg_col, bg_col;
|
||||
uint32_t style, ckey;
|
||||
|
@ -131,7 +132,7 @@ typedef struct tgui_t
|
|||
int pat_x, pat_y;
|
||||
int use_src;
|
||||
|
||||
int src_pitch, dst_pitch, bpp;
|
||||
int pitch, bpp;
|
||||
uint32_t fill_pattern[8*8];
|
||||
uint32_t mono_pattern[8*8];
|
||||
uint32_t pattern_8[8*8];
|
||||
|
@ -144,8 +145,9 @@ typedef struct tgui_t
|
|||
|
||||
uint8_t tgui_3d8, tgui_3d9;
|
||||
int oldmode;
|
||||
uint8_t oldctrl1;
|
||||
uint8_t oldctrl2,newctrl2;
|
||||
uint8_t oldctrl1, newctrl1;
|
||||
uint8_t oldctrl2, newctrl2;
|
||||
uint8_t oldgr0e, newgr0e;
|
||||
|
||||
uint32_t linear_base, linear_size, ge_base,
|
||||
mmio_base;
|
||||
|
@ -292,23 +294,21 @@ tgui_out(uint16_t addr, uint8_t val, void *p)
|
|||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
svga_t *svga = &tgui->svga;
|
||||
uint8_t old, mask;
|
||||
|
||||
mask = (tgui->type >= TGUI_9660) ? 0x3f : 0x1f;
|
||||
uint8_t old;
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C5:
|
||||
switch (svga->seqaddr & 0xf)
|
||||
switch (svga->seqaddr)
|
||||
{
|
||||
case 0xB:
|
||||
tgui->oldmode=1;
|
||||
tgui->oldmode = 1;
|
||||
break;
|
||||
case 0xC:
|
||||
if (svga->seqregs[0xe] & 0x80)
|
||||
svga->seqregs[0xc] = val;
|
||||
if (svga->seqregs[0x0e] & 0x80)
|
||||
svga->seqregs[0x0c] = val;
|
||||
break;
|
||||
case 0xd:
|
||||
if (tgui->oldmode)
|
||||
|
@ -320,12 +320,13 @@ tgui_out(uint16_t addr, uint8_t val, void *p)
|
|||
if (tgui->oldmode) {
|
||||
tgui->oldctrl1 = val;
|
||||
tgui_update_irqs(tgui);
|
||||
} else {
|
||||
svga->seqregs[0xe] = (val ^ 2);
|
||||
svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536;
|
||||
if (!(svga->gdcreg[0xf] & 1))
|
||||
svga->read_bank = svga->write_bank;
|
||||
svga->write_bank = (tgui->oldctrl1) * 65536;
|
||||
} else {
|
||||
svga->seqregs[0xe] = val ^ 2;
|
||||
svga->write_bank = (svga->seqregs[0xe]) * 65536;
|
||||
}
|
||||
if (!(svga->gdcreg[0xf] & 1))
|
||||
svga->read_bank = svga->write_bank;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
@ -340,16 +341,16 @@ tgui_out(uint16_t addr, uint8_t val, void *p)
|
|||
{
|
||||
tgui->ramdac_state = 0;
|
||||
tgui->ramdac_ctrl = val;
|
||||
switch (tgui->ramdac_ctrl & 0xf0)
|
||||
switch ((tgui->ramdac_ctrl >> 4) & 0x0f)
|
||||
{
|
||||
case 0x10:
|
||||
case 1:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 0x30:
|
||||
case 3:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 0xd0:
|
||||
svga->bpp = ((svga->crtc[0x38] & 0x08) == 0x08 && (tgui->type == TGUI_9440)) ? 24 : 32;
|
||||
case 0x0d:
|
||||
svga->bpp = (tgui->type >= TGUI_9660) ? 32 : 24;
|
||||
break;
|
||||
default:
|
||||
svga->bpp = 8;
|
||||
|
@ -366,7 +367,7 @@ tgui_out(uint16_t addr, uint8_t val, void *p)
|
|||
tkd8001_ramdac_out(addr, val, svga->ramdac, svga);
|
||||
return;
|
||||
}
|
||||
tgui->ramdac_state = 0;
|
||||
tgui->ramdac_state = 0;
|
||||
break;
|
||||
|
||||
case 0x3CF:
|
||||
|
@ -383,26 +384,45 @@ tgui_out(uint16_t addr, uint8_t val, void *p)
|
|||
tgui_recalcmapping(tgui);
|
||||
return;
|
||||
}
|
||||
switch (svga->gdcaddr & 15)
|
||||
switch (svga->gdcaddr)
|
||||
{
|
||||
case 0x6:
|
||||
if (svga->gdcreg[6] != val)
|
||||
{
|
||||
svga->gdcreg[6] = val;
|
||||
tgui_recalcmapping(tgui);
|
||||
}
|
||||
return;
|
||||
case 0x6:
|
||||
if (svga->gdcreg[6] != val)
|
||||
{
|
||||
svga->gdcreg[6] = val;
|
||||
tgui_recalcmapping(tgui);
|
||||
}
|
||||
return;
|
||||
|
||||
case 0xE:
|
||||
case 0x0e:
|
||||
svga->gdcreg[0xe] = val ^ 2;
|
||||
if ((svga->gdcreg[0xf] & 1) == 1)
|
||||
svga->read_bank = (svga->gdcreg[0xe] & 0xf) * 65536;
|
||||
svga->read_bank = (svga->gdcreg[0xe]) * 65536;
|
||||
break;
|
||||
case 0xF:
|
||||
if (val & 1) svga->read_bank = (svga->gdcreg[0xe] & 0xf) *65536;
|
||||
else svga->read_bank = (svga->seqregs[0xe] & 0xf) *65536;
|
||||
svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536;
|
||||
case 0x0f:
|
||||
if (val & 1)
|
||||
svga->read_bank = (svga->gdcreg[0xe]) * 65536;
|
||||
else {
|
||||
if (tgui->oldmode)
|
||||
svga->read_bank = (tgui->oldctrl1) * 65536;
|
||||
else
|
||||
svga->read_bank = (svga->seqregs[0xe]) * 65536;
|
||||
}
|
||||
|
||||
if (tgui->oldmode)
|
||||
svga->write_bank = (tgui->oldctrl1) * 65536;
|
||||
else
|
||||
svga->write_bank = (svga->seqregs[0xe]) * 65536;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
case 0x5b:
|
||||
case 0x5c:
|
||||
case 0x5d:
|
||||
case 0x5e:
|
||||
case 0x5f:
|
||||
svga->gdcreg[svga->gdcaddr] = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x3D4:
|
||||
|
@ -430,7 +450,7 @@ tgui_out(uint16_t addr, uint8_t val, void *p)
|
|||
}
|
||||
}
|
||||
switch (svga->crtcreg) {
|
||||
case 0x1e:
|
||||
case 0x1e:
|
||||
svga->vram_display_mask = (val & 0x80) ? tgui->vram_mask : 0x3ffff;
|
||||
break;
|
||||
|
||||
|
@ -441,6 +461,7 @@ tgui_out(uint16_t addr, uint8_t val, void *p)
|
|||
tgui->linear_size = (val & 0x10) ? 0x200000 : 0x100000;
|
||||
svga->decode_mask = (val & 0x10) ? 0x1fffff : 0xfffff;
|
||||
}
|
||||
pclog("Linear base = %08x, size = %08x, mask = %08x\n", tgui->linear_base, tgui->linear_size, svga->decode_mask);
|
||||
tgui_recalcmapping(tgui);
|
||||
}
|
||||
break;
|
||||
|
@ -457,11 +478,6 @@ tgui_out(uint16_t addr, uint8_t val, void *p)
|
|||
case 0x39:
|
||||
tgui_recalcmapping(tgui);
|
||||
break;
|
||||
|
||||
case 0x37:
|
||||
if (tgui->type >= TGUI_9660)
|
||||
i2c_gpio_set(tgui->i2c, !!(val & 0x02), (val & 0x01));
|
||||
break;
|
||||
|
||||
case 0x40: case 0x41: case 0x42: case 0x43:
|
||||
case 0x44: case 0x45: case 0x46: case 0x47:
|
||||
|
@ -486,19 +502,20 @@ tgui_out(uint16_t addr, uint8_t val, void *p)
|
|||
}
|
||||
return;
|
||||
|
||||
case 0x3D8:
|
||||
tgui->tgui_3d8 = val;
|
||||
if (svga->gdcreg[0xf] & 4) {
|
||||
svga->write_bank = (val & mask) * 65536;
|
||||
if (!(svga->gdcreg[0xf] & 1))
|
||||
svga->read_bank = (val & mask) * 65536;
|
||||
}
|
||||
return;
|
||||
case 0x3D8:
|
||||
tgui->tgui_3d8 = val;
|
||||
if (svga->gdcreg[0xf] & 4) {
|
||||
svga->write_bank = (val & 0x3f) * 65536;
|
||||
if (!(svga->gdcreg[0xf] & 1)) {
|
||||
svga->read_bank = (val & 0x3f) * 65536;
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 0x3D9:
|
||||
tgui->tgui_3d9 = val;
|
||||
if ((svga->gdcreg[0xf] & 5) == 5)
|
||||
svga->read_bank = (val & mask) * 65536;
|
||||
return;
|
||||
tgui->tgui_3d9 = val;
|
||||
if ((svga->gdcreg[0xf] & 5) == 5)
|
||||
svga->read_bank = (val & 0x3f) * 65536;
|
||||
return;
|
||||
|
||||
case 0x43c8:
|
||||
tgui->clock_n = val & 0x7f;
|
||||
|
@ -524,11 +541,11 @@ tgui_in(uint16_t addr, void *p)
|
|||
switch (addr)
|
||||
{
|
||||
case 0x3C5:
|
||||
if ((svga->seqaddr & 0xf) == 9) {
|
||||
if (svga->seqaddr == 9) {
|
||||
if (tgui->type == TGUI_9680)
|
||||
return 0x01; /*TGUI9680XGi*/
|
||||
}
|
||||
if ((svga->seqaddr & 0xf) == 0xb)
|
||||
if (svga->seqaddr == 0x0b)
|
||||
{
|
||||
tgui->oldmode = 0;
|
||||
switch (tgui->type)
|
||||
|
@ -542,16 +559,22 @@ tgui_in(uint16_t addr, void *p)
|
|||
return 0xd3; /*TGUI9660XGi*/
|
||||
}
|
||||
}
|
||||
if ((svga->seqaddr & 0xf) == 0xd)
|
||||
if (svga->seqaddr == 0x0d)
|
||||
{
|
||||
if (tgui->oldmode)
|
||||
return tgui->oldctrl2;
|
||||
return tgui->newctrl2;
|
||||
}
|
||||
if ((svga->seqaddr & 0xf) == 0xe)
|
||||
if (svga->seqaddr == 0x0c)
|
||||
{
|
||||
if (svga->seqregs[0x0e] & 0x80)
|
||||
return svga->seqregs[0x0c];
|
||||
}
|
||||
if (svga->seqaddr == 0x0e)
|
||||
{
|
||||
if (tgui->oldmode)
|
||||
return tgui->oldctrl1;
|
||||
return tgui->oldctrl1 | 0x88;
|
||||
return svga->seqregs[0x0e];
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -572,19 +595,13 @@ tgui_in(uint16_t addr, void *p)
|
|||
case 0x3CF:
|
||||
if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32)
|
||||
return tgui->ext_gdc_regs[svga->gdcaddr & 15];
|
||||
break;
|
||||
if (svga->gdcaddr >= 0x5a && svga->gdcaddr <= 0x5f)
|
||||
return svga->gdcreg[svga->gdcaddr];
|
||||
break;
|
||||
case 0x3D4:
|
||||
return svga->crtcreg;
|
||||
case 0x3D5:
|
||||
temp = svga->crtc[svga->crtcreg];
|
||||
if (svga->crtcreg == 0x37) {
|
||||
if (tgui->type >= TGUI_9660) {
|
||||
if ((svga->crtc[0x37] & 0x02) && i2c_gpio_get_scl(tgui->i2c))
|
||||
temp |= 0x02;
|
||||
if ((svga->crtc[0x37] & 0x01) && i2c_gpio_get_sda(tgui->i2c))
|
||||
temp |= 0x01;
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
case 0x3d8:
|
||||
return tgui->tgui_3d8;
|
||||
|
@ -611,14 +628,17 @@ void tgui_recalctimings(svga_t *svga)
|
|||
svga->rowoffset <<= 1;
|
||||
}
|
||||
|
||||
if ((svga->crtc[0x1e] & 0xa0) == 0xa0)
|
||||
|
||||
|
||||
if ((svga->crtc[0x1e] & 0xA0) == 0xA0)
|
||||
svga->ma_latch |= 0x10000;
|
||||
if (svga->crtc[0x27] & 0x01)
|
||||
if ((svga->crtc[0x27] & 0x01) == 0x01)
|
||||
svga->ma_latch |= 0x20000;
|
||||
if (svga->crtc[0x27] & 0x02)
|
||||
if ((svga->crtc[0x27] & 0x02) == 0x02)
|
||||
svga->ma_latch |= 0x40000;
|
||||
if (svga->crtc[0x27] & 0x04)
|
||||
if ((svga->crtc[0x27] & 0x04) == 0x04)
|
||||
svga->ma_latch |= 0x80000;
|
||||
|
||||
if (svga->crtc[0x27] & 0x08)
|
||||
svga->split |= 0x400;
|
||||
if (svga->crtc[0x27] & 0x10)
|
||||
|
@ -635,7 +655,7 @@ void tgui_recalctimings(svga_t *svga)
|
|||
svga->lowres = 0;
|
||||
}
|
||||
|
||||
if (((tgui->oldctrl2 & 0x10) && (svga->crtc[0x1e] & 0x20) && (tgui->oldctrl1 & 1)) || (svga->crtc[0x2a] & 0x40)) /*According to vgadoc*/
|
||||
if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40))
|
||||
svga->ma_latch <<= 1;
|
||||
|
||||
svga->lowres = !(svga->crtc[0x2a] & 0x40);
|
||||
|
@ -711,6 +731,11 @@ void tgui_recalctimings(svga_t *svga)
|
|||
break;
|
||||
case 32:
|
||||
svga->render = svga_render_32bpp_highres;
|
||||
if (tgui->type >= TGUI_9660) {
|
||||
if (svga->hdisp == 1024) {
|
||||
svga->rowoffset <<= 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -888,7 +913,7 @@ uint8_t tgui_pci_read(int func, int addr, void *p)
|
|||
case 0x02: return (tgui->type == TGUI_9440) ? 0x40 : 0x60; /*TGUI9440AGi or TGUI9660XGi*/
|
||||
case 0x03: return (tgui->type == TGUI_9440) ? 0x94 : 0x96;
|
||||
|
||||
case PCI_REG_COMMAND: return tgui->pci_regs[PCI_REG_COMMAND] & 0x23; /*Respond to IO and memory accesses*/
|
||||
case PCI_REG_COMMAND: return tgui->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/
|
||||
|
||||
case 0x07: return 1 << 1; /*Medium DEVSEL timing*/
|
||||
|
||||
|
@ -942,7 +967,6 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p)
|
|||
tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xe0) << 16);
|
||||
tgui->linear_size = tgui->vram_size;
|
||||
svga->decode_mask = tgui->vram_mask;
|
||||
svga->crtc[0x21] = (svga->crtc[0x21] & ~0xf) | (val >> 4);
|
||||
tgui_recalcmapping(tgui);
|
||||
break;
|
||||
case 0x13:
|
||||
|
@ -952,7 +976,6 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p)
|
|||
tgui->linear_base = (tgui->linear_base & 0xe00000) | (val << 24);
|
||||
tgui->linear_size = tgui->vram_size;
|
||||
svga->decode_mask = tgui->vram_mask;
|
||||
svga->crtc[0x21] = (svga->crtc[0x21] & ~0xc0) | (val >> 6);
|
||||
tgui_recalcmapping(tgui);
|
||||
break;
|
||||
|
||||
|
@ -1204,7 +1227,8 @@ enum
|
|||
{
|
||||
TGUI_BITBLT = 1,
|
||||
TGUI_SCANLINE = 3,
|
||||
TGUI_BRESENHAMLINE = 4
|
||||
TGUI_BRESENHAMLINE = 4,
|
||||
TGUI_SHORTVECTOR = 5
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -1333,62 +1357,88 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
|||
}
|
||||
|
||||
/*Other than mode stuff, this bit is undocumented*/
|
||||
pclog("TGUI ger22 = %04x, cmd = %i, hdisp = %i, svga = %i, bpp = %i\n", tgui->accel.ger22, tgui->accel.command, svga->hdisp, svga->bpp, tgui->accel.bpp);
|
||||
switch (tgui->accel.ger22 & 0xff) {
|
||||
case 0:
|
||||
switch (tgui->accel.ger22 >> 8) {
|
||||
case 0x41:
|
||||
tgui->accel.pitch = 640;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
tgui->accel.src_pitch = 1024;
|
||||
tgui->accel.dst_pitch = 1024;
|
||||
if (svga->hdisp == 800) {
|
||||
if ((tgui->accel.ger22 >> 8) > 0) {
|
||||
tgui->accel.src_pitch = 832;
|
||||
tgui->accel.dst_pitch = 832;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
tgui->accel.src_pitch = 2048;
|
||||
tgui->accel.dst_pitch = 2048;
|
||||
if (tgui->type >= TGUI_9660) {
|
||||
tgui->accel.src_pitch = 1280;
|
||||
tgui->accel.dst_pitch = 1280;
|
||||
}
|
||||
break;
|
||||
|
||||
case 9:
|
||||
tgui->accel.src_pitch = 1024;
|
||||
tgui->accel.dst_pitch = 1024;
|
||||
if (tgui->type >= TGUI_9660) {
|
||||
tgui->accel.src_pitch = svga->hdisp;
|
||||
tgui->accel.dst_pitch = svga->hdisp;
|
||||
if (svga->hdisp == 800) {
|
||||
tgui->accel.src_pitch = 832;
|
||||
tgui->accel.dst_pitch = 832;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 14:
|
||||
tgui->accel.src_pitch = svga->hdisp;
|
||||
tgui->accel.dst_pitch = svga->hdisp;
|
||||
switch (tgui->svga.bpp) {
|
||||
case 32:
|
||||
if (svga->hdisp == 800) {
|
||||
tgui->accel.src_pitch = 832;
|
||||
tgui->accel.dst_pitch = 832;
|
||||
switch (tgui->accel.ger22 >> 8) {
|
||||
case 0:
|
||||
tgui->accel.pitch = 1024;
|
||||
break;
|
||||
case 0x40:
|
||||
tgui->accel.pitch = 640;
|
||||
break;
|
||||
case 0x50:
|
||||
tgui->accel.pitch = 832;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
switch (tgui->accel.ger22 >> 8) {
|
||||
case 0:
|
||||
tgui->accel.pitch = 2048;
|
||||
break;
|
||||
case 0x60:
|
||||
tgui->accel.pitch = 1280;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
switch (tgui->accel.ger22 >> 8) {
|
||||
case 0:
|
||||
tgui->accel.pitch = svga->hdisp;
|
||||
if (tgui->type == TGUI_9440)
|
||||
tgui->accel.pitch = 1024;
|
||||
break;
|
||||
case 0x40:
|
||||
tgui->accel.pitch = 640;
|
||||
break;
|
||||
case 0x50:
|
||||
tgui->accel.pitch = 832;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
switch (tgui->accel.ger22 >> 8) {
|
||||
case 0x60:
|
||||
tgui->accel.pitch = 2048;
|
||||
if (tgui->type >= TGUI_9660) {
|
||||
if (svga->hdisp == 1280)
|
||||
tgui->accel.pitch = svga->hdisp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
switch (tgui->accel.ger22 >> 8) {
|
||||
case 0:
|
||||
tgui->accel.pitch = 1024;
|
||||
break;
|
||||
case 0x40:
|
||||
tgui->accel.pitch = 640;
|
||||
break;
|
||||
case 0x50:
|
||||
tgui->accel.pitch = 832;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (tgui->accel.command)
|
||||
{
|
||||
case TGUI_BITBLT:
|
||||
if (count == -1) {
|
||||
tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.src_pitch);
|
||||
tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch);
|
||||
tgui->accel.src = tgui->accel.src_old;
|
||||
|
||||
tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.dst_pitch);
|
||||
tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch);
|
||||
tgui->accel.dst = tgui->accel.dst_old;
|
||||
|
||||
tgui->accel.pat_x = tgui->accel.dst_x;
|
||||
|
@ -1473,8 +1523,8 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
|||
tgui->accel.dy += ydir;
|
||||
}
|
||||
|
||||
tgui->accel.src_old += (ydir * tgui->accel.src_pitch);
|
||||
tgui->accel.dst_old += (ydir * tgui->accel.dst_pitch);
|
||||
tgui->accel.src_old += (ydir * tgui->accel.pitch);
|
||||
tgui->accel.dst_old += (ydir * tgui->accel.pitch);
|
||||
|
||||
tgui->accel.src = tgui->accel.src_old;
|
||||
tgui->accel.dst = tgui->accel.dst_old;
|
||||
|
@ -1535,8 +1585,8 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
|||
tgui->accel.pat_x = tgui->accel.dst_x;
|
||||
tgui->accel.pat_y += ydir;
|
||||
|
||||
tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.src_pitch);
|
||||
tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.dst_pitch);
|
||||
tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch);
|
||||
tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch);
|
||||
|
||||
tgui->accel.y++;
|
||||
|
||||
|
@ -1582,8 +1632,8 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
|||
tgui->accel.pat_x = tgui->accel.dst_x;
|
||||
tgui->accel.pat_y += ydir;
|
||||
|
||||
tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.src_pitch);
|
||||
tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.dst_pitch);
|
||||
tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch);
|
||||
tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch);
|
||||
|
||||
if (tgui->accel.y > tgui->accel.size_y)
|
||||
return;
|
||||
|
@ -1596,10 +1646,10 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
|||
case TGUI_SCANLINE:
|
||||
{
|
||||
if (count == -1) {
|
||||
tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.src_pitch);
|
||||
tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch);
|
||||
tgui->accel.src = tgui->accel.src_old;
|
||||
|
||||
tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.dst_pitch);
|
||||
tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch);
|
||||
tgui->accel.dst = tgui->accel.dst_old;
|
||||
|
||||
tgui->accel.pat_x = tgui->accel.dst_x;
|
||||
|
@ -1633,8 +1683,8 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
|||
tgui->accel.x = 0;
|
||||
|
||||
tgui->accel.pat_x = tgui->accel.dst_x;
|
||||
tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.src_pitch);
|
||||
tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.dst_pitch);
|
||||
tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch);
|
||||
tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch);
|
||||
tgui->accel.pat_y += ydir;
|
||||
return;
|
||||
}
|
||||
|
@ -1691,13 +1741,13 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
|||
}
|
||||
|
||||
while (count--) {
|
||||
READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.src_pitch), src_dat);
|
||||
READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat);
|
||||
|
||||
/*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/
|
||||
if (steep) {
|
||||
if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right &&
|
||||
dy >= tgui->accel.top && dy <= tgui->accel.bottom)) {
|
||||
READ(dx + (dy * tgui->accel.dst_pitch), dst_dat);
|
||||
READ(dx + (dy * tgui->accel.pitch), dst_dat);
|
||||
|
||||
pat_dat = tgui->accel.fg_col;
|
||||
|
||||
|
@ -1708,12 +1758,12 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
|||
|
||||
MIX();
|
||||
|
||||
WRITE(dx + (dy * tgui->accel.dst_pitch), out);
|
||||
WRITE(dx + (dy * tgui->accel.pitch), out);
|
||||
}
|
||||
} else {
|
||||
if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dy >= tgui->accel.left && dy <= tgui->accel.right &&
|
||||
dx >= tgui->accel.top && dx <= tgui->accel.bottom)) {
|
||||
READ(dy + (dx * tgui->accel.dst_pitch), dst_dat);
|
||||
dx >= tgui->accel.top && dx <= tgui->accel.bottom)) {
|
||||
READ(dy + (dx * tgui->accel.pitch), dst_dat);
|
||||
|
||||
pat_dat = tgui->accel.fg_col;
|
||||
|
||||
|
@ -1724,7 +1774,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
|||
|
||||
MIX();
|
||||
|
||||
WRITE(dy + (dx * tgui->accel.dst_pitch), out);
|
||||
WRITE(dy + (dx * tgui->accel.pitch), out);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1742,13 +1792,92 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TGUI_SHORTVECTOR:
|
||||
{
|
||||
int16_t dx, dy;
|
||||
|
||||
dx = tgui->accel.dst_x & 0xfff;
|
||||
dy = tgui->accel.dst_y & 0xfff;
|
||||
|
||||
tgui->accel.left = tgui->accel.src_x_clip & 0xfff;
|
||||
tgui->accel.right = tgui->accel.dst_x_clip & 0xfff;
|
||||
tgui->accel.top = tgui->accel.src_y_clip & 0xfff;
|
||||
tgui->accel.bottom = tgui->accel.dst_y_clip & 0xfff;
|
||||
|
||||
if (tgui->accel.bpp == 1) {
|
||||
tgui->accel.left >>= 1;
|
||||
tgui->accel.right >>= 1;
|
||||
} else if (tgui->accel.bpp == 3) {
|
||||
tgui->accel.left >>= 2;
|
||||
tgui->accel.right >>= 2;
|
||||
}
|
||||
|
||||
while (count--) {
|
||||
READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat);
|
||||
|
||||
/*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/
|
||||
if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right &&
|
||||
dy >= tgui->accel.top && dy <= tgui->accel.bottom)) {
|
||||
READ(dx + (dy * tgui->accel.pitch), dst_dat);
|
||||
|
||||
pat_dat = tgui->accel.fg_col;
|
||||
|
||||
if (tgui->accel.bpp == 0)
|
||||
pat_dat &= 0xff;
|
||||
else if (tgui->accel.bpp == 1)
|
||||
pat_dat &= 0xffff;
|
||||
|
||||
MIX();
|
||||
|
||||
WRITE(dx + (dy * tgui->accel.pitch), out);
|
||||
}
|
||||
|
||||
if (tgui->accel.y == (tgui->accel.sv_size_y & 0xfff))
|
||||
break;
|
||||
|
||||
switch ((tgui->accel.sv_size_y >> 8) & 0xe0) {
|
||||
case 0x00:
|
||||
dx++;
|
||||
break;
|
||||
case 0x20:
|
||||
dx++;
|
||||
dy--;
|
||||
break;
|
||||
case 0x40:
|
||||
dy--;
|
||||
break;
|
||||
case 0x60:
|
||||
dx--;
|
||||
dy--;
|
||||
break;
|
||||
case 0x80:
|
||||
dx--;
|
||||
break;
|
||||
case 0xa0:
|
||||
dx--;
|
||||
dy++;
|
||||
break;
|
||||
case 0xc0:
|
||||
dy++;
|
||||
break;
|
||||
case 0xe0:
|
||||
dx++;
|
||||
dy++;
|
||||
break;
|
||||
}
|
||||
|
||||
tgui->accel.y++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tgui_accel_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
|
@ -1764,6 +1893,7 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p)
|
|||
tgui->accel.bpp = 1;
|
||||
break;
|
||||
|
||||
case 13:
|
||||
case 14:
|
||||
switch (tgui->svga.bpp) {
|
||||
case 15:
|
||||
|
@ -1885,9 +2015,11 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p)
|
|||
break;
|
||||
case 0x2142: /*Size Y*/
|
||||
tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val;
|
||||
tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff00) | val;
|
||||
break;
|
||||
case 0x2143: /*Size Y*/
|
||||
tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8);
|
||||
tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x2144: /*Style*/
|
||||
|
@ -2186,8 +2318,8 @@ tgui_accel_in_l(uint16_t addr, void *p)
|
|||
static void
|
||||
tgui_accel_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
svga_t *svga = &tgui->svga;
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
svga_t *svga = &tgui->svga;
|
||||
|
||||
if ((svga->crtc[0x36] & 0x03) == 0x02) {
|
||||
if ((addr & ~0xff) != 0xbff00)
|
||||
|
@ -2211,6 +2343,7 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p)
|
|||
tgui->accel.bpp = 1;
|
||||
break;
|
||||
|
||||
case 13:
|
||||
case 14:
|
||||
switch (tgui->svga.bpp) {
|
||||
case 15:
|
||||
|
@ -2332,9 +2465,11 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p)
|
|||
break;
|
||||
case 0x42: /*Size Y*/
|
||||
tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val;
|
||||
tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff00) | val;
|
||||
break;
|
||||
case 0x43: /*Size Y*/
|
||||
tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8);
|
||||
tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x44: /*Style*/
|
||||
|
@ -2858,7 +2993,7 @@ static void *tgui_init(const device_t *info)
|
|||
if (tgui->pci && (tgui->type >= TGUI_9440))
|
||||
tgui->card = pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui);
|
||||
|
||||
tgui->pci_regs[PCI_REG_COMMAND] = 3;
|
||||
tgui->pci_regs[PCI_REG_COMMAND] = 7;
|
||||
|
||||
tgui->pci_regs[0x30] = 0x00;
|
||||
tgui->pci_regs[0x32] = 0x0c;
|
||||
|
@ -2866,11 +3001,6 @@ static void *tgui_init(const device_t *info)
|
|||
|
||||
if (tgui->type >= TGUI_9440)
|
||||
svga->packed_chain4 = 1;
|
||||
|
||||
if (tgui->type >= TGUI_9660) {
|
||||
tgui->i2c = i2c_gpio_init("ddc_tgui");
|
||||
tgui->ddc = ddc_init(i2c_gpio_get_bus(tgui->i2c));
|
||||
}
|
||||
|
||||
return tgui;
|
||||
}
|
||||
|
@ -2896,11 +3026,6 @@ void tgui_close(void *p)
|
|||
|
||||
svga_close(&tgui->svga);
|
||||
|
||||
if (tgui->type >= TGUI_9660) {
|
||||
ddc_close(tgui->ddc);
|
||||
i2c_gpio_close(tgui->i2c);
|
||||
}
|
||||
|
||||
free(tgui);
|
||||
}
|
||||
|
||||
|
|
472
src/video/vid_tvp3026_ramdac.c
Normal file
472
src/video/vid_tvp3026_ramdac.c
Normal file
|
@ -0,0 +1,472 @@
|
|||
/*
|
||||
* 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 Texas Instruments TVP3026 true colour RAMDAC
|
||||
* family.
|
||||
*
|
||||
*
|
||||
* TODO: Clock and other parts.
|
||||
*
|
||||
* Authors: TheCollector1995,
|
||||
*
|
||||
* Copyright 2021 TheCollector1995.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PALETTE extpal;
|
||||
uint32_t extpallook[256];
|
||||
uint8_t cursor64_data[1024];
|
||||
int hwc_y, hwc_x;
|
||||
uint8_t ind_idx;
|
||||
uint8_t dcc, dc_init;
|
||||
uint8_t ccr;
|
||||
uint8_t true_color;
|
||||
uint8_t latch_cntl;
|
||||
uint8_t mcr;
|
||||
uint8_t ppr;
|
||||
uint8_t general_cntl;
|
||||
uint8_t mclk;
|
||||
uint8_t misc;
|
||||
uint8_t type;
|
||||
uint8_t mode;
|
||||
} tvp3026_ramdac_t;
|
||||
|
||||
static void
|
||||
tvp3026_set_bpp(tvp3026_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
if ((ramdac->true_color & 0x80) == 0x80) {
|
||||
if (ramdac->mcr & 0x08)
|
||||
svga->bpp = 8;
|
||||
else
|
||||
svga->bpp = 4;
|
||||
} else {
|
||||
switch (ramdac->true_color & 0x0f) {
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
case 0x05:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 0x04:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
if (ramdac->true_color & 0x10)
|
||||
svga->bpp = 24;
|
||||
else
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
case 0x0e:
|
||||
case 0x0f:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
}
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga)
|
||||
{
|
||||
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p;
|
||||
uint32_t o32;
|
||||
uint8_t *cd;
|
||||
uint16_t index;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
uint16_t da_mask = 0x03ff;
|
||||
rs |= (!!rs2 << 2);
|
||||
rs |= (!!rs3 << 3);
|
||||
|
||||
|
||||
switch (rs) {
|
||||
case 0x00: /* Palette Write Index Register (RS value = 0000) */
|
||||
ramdac->ind_idx = val;
|
||||
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
|
||||
case 0x03:
|
||||
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
|
||||
svga->dac_pos = 0;
|
||||
svga->dac_status = addr & 0x03;
|
||||
svga->dac_addr = val;
|
||||
if (svga->dac_status)
|
||||
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
|
||||
break;
|
||||
case 0x01: /* Palette Data Register (RS value = 0001) */
|
||||
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
case 0x05: /* Ext Palette Data Register (RS value = 0101) */
|
||||
svga->dac_status = 0;
|
||||
svga->fullchange = changeframecount;
|
||||
switch (svga->dac_pos) {
|
||||
case 0:
|
||||
svga->dac_r = val;
|
||||
svga->dac_pos++;
|
||||
break;
|
||||
case 1:
|
||||
svga->dac_g = val;
|
||||
svga->dac_pos++;
|
||||
break;
|
||||
case 2:
|
||||
index = svga->dac_addr & 3;
|
||||
ramdac->extpal[index].r = svga->dac_r;
|
||||
ramdac->extpal[index].g = svga->dac_g;
|
||||
ramdac->extpal[index].b = val;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->extpallook[index] = makecol32(ramdac->extpal[index].r, ramdac->extpal[index].g, ramdac->extpal[index].b);
|
||||
else
|
||||
ramdac->extpallook[index] = makecol32(video_6to8[ramdac->extpal[index].r & 0x3f], video_6to8[ramdac->extpal[index].g & 0x3f], video_6to8[ramdac->extpal[index].b & 0x3f]);
|
||||
|
||||
if (svga->ext_overscan && !index) {
|
||||
o32 = svga->overscan_color;
|
||||
svga->overscan_color = ramdac->extpallook[0];
|
||||
if (o32 != svga->overscan_color)
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
svga->dac_addr = (svga->dac_addr + 1) & 0xff;
|
||||
svga->dac_pos = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x09: /* Direct Cursor Control (RS value = 1001) */
|
||||
ramdac->dcc = val;
|
||||
if (ramdac->ccr & 0x80) {
|
||||
svga->dac_hwcursor.xsize = svga->dac_hwcursor.ysize = 64;
|
||||
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize;
|
||||
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize;
|
||||
svga->dac_hwcursor.ena = ((val & 0x03) != 0);
|
||||
ramdac->mode = val & 0x03;
|
||||
}
|
||||
break;
|
||||
case 0x0a: /* Indexed Data (RS value = 1010) */
|
||||
switch (ramdac->ind_idx) {
|
||||
case 0x06: /* Indirect Cursor Control */
|
||||
ramdac->ccr = val;
|
||||
svga->dac_hwcursor.xsize = svga->dac_hwcursor.ysize = 64;
|
||||
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize;
|
||||
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize;
|
||||
svga->dac_hwcursor.ena = ((val & 0x03) != 0);
|
||||
ramdac->mode = val & 0x03;
|
||||
break;
|
||||
case 0x0f: /* Latch Control */
|
||||
ramdac->latch_cntl = val;
|
||||
break;
|
||||
case 0x18: /* True Color Control */
|
||||
ramdac->true_color = val;
|
||||
tvp3026_set_bpp(ramdac, svga);
|
||||
break;
|
||||
case 0x19: /* Multiplex Control */
|
||||
ramdac->mcr = val;
|
||||
tvp3026_set_bpp(ramdac, svga);
|
||||
break;
|
||||
case 0x1c: /* Palette-Page Register */
|
||||
ramdac->ppr = val;
|
||||
break;
|
||||
case 0x1d: /* General Control Register */
|
||||
ramdac->general_cntl = val;
|
||||
break;
|
||||
case 0x1e: /* Miscellaneous Control */
|
||||
ramdac->misc = val;
|
||||
svga->ramdac_type = (val & 0x08) ? RAMDAC_8BIT : RAMDAC_6BIT;
|
||||
break;
|
||||
case 0x39: /* MCLK/Loop Clock Control */
|
||||
ramdac->mclk = val;
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
|
||||
index = svga->dac_addr & da_mask;
|
||||
cd = (uint8_t *) ramdac->cursor64_data;
|
||||
cd[index] = val;
|
||||
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
|
||||
break;
|
||||
case 0x0c: /* Cursor X Low Register (RS value = 1100) */
|
||||
ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val;
|
||||
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize;
|
||||
break;
|
||||
case 0x0d: /* Cursor X High Register (RS value = 1101) */
|
||||
ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8);
|
||||
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize;
|
||||
break;
|
||||
case 0x0e: /* Cursor Y Low Register (RS value = 1110) */
|
||||
ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val;
|
||||
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize;
|
||||
break;
|
||||
case 0x0f: /* Cursor Y High Register (RS value = 1111) */
|
||||
ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8);
|
||||
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
|
||||
{
|
||||
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p;
|
||||
uint8_t temp = 0xff;
|
||||
uint8_t *cd;
|
||||
uint16_t index;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
uint16_t da_mask = 0x03ff;
|
||||
rs |= (!!rs2 << 2);
|
||||
rs |= (!!rs3 << 3);
|
||||
|
||||
switch (rs) {
|
||||
case 0x00: /* Palette Write Index Register (RS value = 0000) */
|
||||
case 0x01: /* Palette Data Register (RS value = 0001) */
|
||||
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
|
||||
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
case 0x03: /* Palette Read Index Register (RS value = 0011) */
|
||||
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
|
||||
temp = svga->dac_addr & 0xff;
|
||||
break;
|
||||
case 0x05: /* Ext Palette Data Register (RS value = 0101) */
|
||||
index = (svga->dac_addr - 1) & 3;
|
||||
svga->dac_status = 3;
|
||||
switch (svga->dac_pos) {
|
||||
case 0:
|
||||
svga->dac_pos++;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
temp = ramdac->extpal[index].r;
|
||||
else
|
||||
temp = ramdac->extpal[index].r & 0x3f;
|
||||
break;
|
||||
case 1:
|
||||
svga->dac_pos++;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
temp = ramdac->extpal[index].g;
|
||||
else
|
||||
temp = ramdac->extpal[index].g & 0x3f;
|
||||
break;
|
||||
case 2:
|
||||
svga->dac_pos=0;
|
||||
svga->dac_addr = svga->dac_addr + 1;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
temp = ramdac->extpal[index].b;
|
||||
else
|
||||
temp = ramdac->extpal[index].b & 0x3f;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x09: /* Direct Cursor Control (RS value = 1001) */
|
||||
temp = ramdac->dcc;
|
||||
break;
|
||||
case 0x0a: /* Indexed Data (RS value = 1010) */
|
||||
switch (ramdac->ind_idx) {
|
||||
case 0x01: /* Silicon Revision */
|
||||
temp = 0x00;
|
||||
break;
|
||||
case 0x06: /* Indirect Cursor Control */
|
||||
temp = ramdac->ccr;
|
||||
break;
|
||||
case 0x0f: /* Latch Control */
|
||||
temp = ramdac->latch_cntl;
|
||||
break;
|
||||
case 0x18: /* True Color Control */
|
||||
temp = ramdac->true_color;
|
||||
break;
|
||||
case 0x19: /* Multiplex Control */
|
||||
temp = ramdac->mcr;
|
||||
break;
|
||||
case 0x1c: /* Palette-Page Register */
|
||||
temp = ramdac->ppr;
|
||||
break;
|
||||
case 0x1d: /* General Control Register */
|
||||
temp = ramdac->general_cntl;
|
||||
break;
|
||||
case 0x1e: /* Miscellaneous Control */
|
||||
temp = ramdac->misc;
|
||||
break;
|
||||
case 0x39: /* MCLK/Loop Clock Control */
|
||||
temp = ramdac->mclk;
|
||||
break;
|
||||
case 0x3f: /* ID */
|
||||
temp = 0x26;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
|
||||
index = (svga->dac_addr - 1) & da_mask;
|
||||
cd = (uint8_t *) ramdac->cursor64_data;
|
||||
temp = cd[index];
|
||||
|
||||
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
|
||||
break;
|
||||
case 0x0c: /* Cursor X Low Register (RS value = 1100) */
|
||||
temp = ramdac->hwc_x & 0xff;
|
||||
break;
|
||||
case 0x0d: /* Cursor X High Register (RS value = 1101) */
|
||||
temp = (ramdac->hwc_x >> 8) & 0xff;
|
||||
break;
|
||||
case 0x0e: /* Cursor Y Low Register (RS value = 1110) */
|
||||
temp = ramdac->hwc_y & 0xff;
|
||||
break;
|
||||
case 0x0f: /* Cursor Y High Register (RS value = 1111) */
|
||||
temp = (ramdac->hwc_y >> 8) & 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
void
|
||||
tvp3026_recalctimings(void *p, svga_t *svga)
|
||||
{
|
||||
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p;
|
||||
|
||||
svga->interlace = (ramdac->ccr & 0x40);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tvp3026_hwcursor_draw(svga_t *svga, int displine)
|
||||
{
|
||||
int x, xx, comb, b0, b1;
|
||||
uint16_t dat[2];
|
||||
int offset = svga->dac_hwcursor_latch.x + svga->dac_hwcursor_latch.xoff;
|
||||
int pitch, bppl, mode, x_pos, y_pos;
|
||||
uint32_t clr1, clr2, clr3, *p;
|
||||
uint8_t *cd;
|
||||
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) svga->ramdac;
|
||||
|
||||
clr1 = ramdac->extpallook[1];
|
||||
clr2 = ramdac->extpallook[2];
|
||||
clr3 = ramdac->extpallook[3];
|
||||
|
||||
/* The planes come in two parts, and each plane is 1bpp,
|
||||
so a 32x32 cursor has 4 bytes per line, and a 64x64
|
||||
cursor has 8 bytes per line. */
|
||||
pitch = (svga->dac_hwcursor_latch.xsize >> 3); /* Bytes per line. */
|
||||
/* A 32x32 cursor has 128 bytes per line, and a 64x64
|
||||
cursor has 512 bytes per line. */
|
||||
bppl = (pitch * svga->dac_hwcursor_latch.ysize); /* Bytes per plane. */
|
||||
mode = ramdac->mode;
|
||||
|
||||
if (svga->interlace && svga->dac_hwcursor_oddeven)
|
||||
svga->dac_hwcursor_latch.addr += pitch;
|
||||
|
||||
cd = (uint8_t *) ramdac->cursor64_data;
|
||||
|
||||
for (x = 0; x < svga->dac_hwcursor_latch.xsize; x += 16) {
|
||||
dat[0] = (cd[svga->dac_hwcursor_latch.addr] << 8) |
|
||||
cd[svga->dac_hwcursor_latch.addr + 1];
|
||||
dat[1] = (cd[svga->dac_hwcursor_latch.addr + bppl] << 8) |
|
||||
cd[svga->dac_hwcursor_latch.addr + bppl + 1];
|
||||
|
||||
for (xx = 0; xx < 16; xx++) {
|
||||
b0 = (dat[0] >> (15 - xx)) & 1;
|
||||
b1 = (dat[1] >> (15 - xx)) & 1;
|
||||
comb = (b0 | (b1 << 1));
|
||||
|
||||
y_pos = displine;
|
||||
x_pos = offset + svga->x_add;
|
||||
p = buffer32->line[y_pos];
|
||||
|
||||
if (offset >= svga->dac_hwcursor_latch.x) {
|
||||
switch (mode) {
|
||||
case 1: /* Three Color */
|
||||
switch (comb) {
|
||||
case 1:
|
||||
p[x_pos] = clr1;
|
||||
break;
|
||||
case 2:
|
||||
p[x_pos] = clr2;
|
||||
break;
|
||||
case 3:
|
||||
p[x_pos] = clr3;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2: /* XGA */
|
||||
switch (comb) {
|
||||
case 0:
|
||||
p[x_pos] = clr1;
|
||||
break;
|
||||
case 1:
|
||||
p[x_pos] = clr2;
|
||||
break;
|
||||
case 3:
|
||||
p[x_pos] ^= 0xffffff;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3: /* X-Windows */
|
||||
switch (comb) {
|
||||
case 2:
|
||||
p[x_pos] = clr1;
|
||||
break;
|
||||
case 3:
|
||||
p[x_pos] = clr2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
svga->dac_hwcursor_latch.addr += 2;
|
||||
}
|
||||
|
||||
if (svga->interlace && !svga->dac_hwcursor_oddeven)
|
||||
svga->dac_hwcursor_latch.addr += pitch;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
tvp3026_ramdac_init(const device_t *info)
|
||||
{
|
||||
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) malloc(sizeof(tvp3026_ramdac_t));
|
||||
memset(ramdac, 0, sizeof(tvp3026_ramdac_t));
|
||||
|
||||
ramdac->type = info->local;
|
||||
|
||||
ramdac->latch_cntl = 0x06;
|
||||
ramdac->true_color = 0x80;
|
||||
ramdac->mcr = 0x98;
|
||||
ramdac->mclk = 0x18;
|
||||
|
||||
return ramdac;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
tvp3026_ramdac_close(void *priv)
|
||||
{
|
||||
tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv;
|
||||
|
||||
if (ramdac)
|
||||
free(ramdac);
|
||||
}
|
||||
|
||||
|
||||
const device_t tvp3026_ramdac_device =
|
||||
{
|
||||
"TI TVP3026 RAMDAC",
|
||||
0, 0,
|
||||
tvp3026_ramdac_init, tvp3026_ramdac_close,
|
||||
NULL, { NULL }, NULL, NULL
|
||||
};
|
|
@ -1237,23 +1237,7 @@ void *voodoo_init()
|
|||
|
||||
void voodoo_card_close(voodoo_t *voodoo)
|
||||
{
|
||||
/* #ifndef RELEASE_BUILD
|
||||
FILE *f;
|
||||
#endif */
|
||||
int c;
|
||||
|
||||
/* #ifndef RELEASE_BUILD
|
||||
f = rom_fopen("texram.dmp", "wb");
|
||||
fwrite(voodoo->tex_mem[0], voodoo->texture_size*1024*1024, 1, f);
|
||||
fclose(f);
|
||||
if (voodoo->dual_tmus)
|
||||
{
|
||||
f = rom_fopen("texram2.dmp", "wb");
|
||||
fwrite(voodoo->tex_mem[1], voodoo->texture_size*1024*1024, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
#endif */
|
||||
|
||||
|
||||
voodoo->fifo_thread_run = 0;
|
||||
thread_set_event(voodoo->wake_fifo_thread);
|
||||
|
|
|
@ -779,7 +779,8 @@ VIDOBJ := video.o \
|
|||
vid_s3.o vid_s3_virge.o \
|
||||
vid_ibm_rgb528_ramdac.o vid_sdac_ramdac.o \
|
||||
vid_ogc.o \
|
||||
vid_nga.o
|
||||
vid_nga.o \
|
||||
vid_tvp3026_ramdac.o
|
||||
|
||||
VOODOOOBJ := vid_voodoo.o vid_voodoo_banshee.o \
|
||||
vid_voodoo_banshee_blitter.o \
|
||||
|
@ -838,7 +839,7 @@ LIBS += -static
|
|||
ifeq ($(AUTODEP), y)
|
||||
%.o: %.c
|
||||
@echo $<
|
||||
$(CC) $(CFLAGS) $(DEPS) -c $<
|
||||
@$(CC) $(CFLAGS) $(DEPS) -c $<
|
||||
|
||||
%.o: %.cc
|
||||
@echo $<
|
||||
|
|
|
@ -288,7 +288,8 @@ sdl_destroy_texture(void)
|
|||
void
|
||||
sdl_close(void)
|
||||
{
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
if (sdl_mutex != NULL)
|
||||
SDL_LockMutex(sdl_mutex);
|
||||
|
||||
/* Unregister our renderer! */
|
||||
video_setblit(NULL);
|
||||
|
|
Loading…
Add table
Reference in a new issue