From 7533bdd520749031232700512d8d6fe216f67487 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 4 Oct 2018 03:31:42 +0200 Subject: [PATCH] Removed even more excess files. --- backup code/config - Cópia.c | 2174 ----- backup code/disk/hdc_esdi_mfm.c | 856 -- backup code/disk/hdc_ide - Cópia.c | 3023 ------- backup code/disk/zip - Cópia.c | 2859 ------ backup code/disk/zip - Cópia.h | 156 - backup code/dma.c.old | 853 -- backup code/dma.h.old | 74 - backup code/intel_piix - Cópia.c | 916 -- backup code/keyboard_at.c.old | 2097 ----- backup code/mouse_bus - Cópia (2).c | 876 -- backup code/mouse_bus - Cópia (3).c | 632 -- backup code/mouse_bus - Cópia (4).c | 805 -- backup code/mouse_bus - Cópia 2.c | 877 -- backup code/mouse_bus - Cópia.c | 794 -- backup code/mouse_bus_good.c | 879 -- backup code/mouse_bus_x.c | 795 -- backup code/network/net_pcap - Cópia.c | 364 - backup code/pc - Cópia.c | 1130 --- backup code/scsi/scsi - Cópia (2).h | 368 - backup code/scsi/scsi - Cópia.c | 236 - backup code/scsi/scsi - Cópia.h | 378 - backup code/scsi/scsi_device - Cópia (2).c | 415 - backup code/scsi/scsi_device - Cópia.c | 416 - backup code/scsi/scsi_device - Cópia.h | 69 - backup code/scsi/scsi_disk - Cópia.c | 1291 --- backup code/scsi/scsi_disk - Cópia.h | 45 - backup code/scsi/scsi_null.c | 395 - backup code/video - Cópia/vid_ati18800.c | 305 - backup code/video - Cópia/vid_ati18800.h | 6 - backup code/video - Cópia/vid_ati28800.c | 645 -- backup code/video - Cópia/vid_ati28800.h | 9 - .../video - Cópia/vid_ati68860_ramdac.c | 197 - .../video - Cópia/vid_ati68860_ramdac.h | 20 - backup code/video - Cópia/vid_ati_eeprom.c | 235 - backup code/video - Cópia/vid_ati_eeprom.h | 19 - backup code/video - Cópia/vid_ati_mach64.c | 3513 -------- backup code/video - Cópia/vid_ati_mach64.h | 22 - backup code/video - Cópia/vid_bt485_ramdac.c | 192 - backup code/video - Cópia/vid_bt485_ramdac.h | 18 - backup code/video - Cópia/vid_cga.c | 598 -- backup code/video - Cópia/vid_cga.h | 65 - backup code/video - Cópia/vid_cga_comp.c | 345 - backup code/video - Cópia/vid_cga_comp.h | 27 - .../video - Cópia/vid_cl54xx - Cópia.c | 2685 ------ backup code/video - Cópia/vid_cl54xx.c | 2691 ------ backup code/video - Cópia/vid_cl54xx.h | 19 - backup code/video - Cópia/vid_colorplus.c | 477 - backup code/video - Cópia/vid_colorplus.h | 15 - backup code/video - Cópia/vid_compaq_cga.c | 461 - backup code/video - Cópia/vid_compaq_cga.h | 11 - backup code/video - Cópia/vid_ega.c | 1293 --- backup code/video - Cópia/vid_ega.h | 149 - backup code/video - Cópia/vid_ega_render.c | 550 -- backup code/video - Cópia/vid_ega_render.h | 39 - backup code/video - Cópia/vid_et4000.c | 218 - backup code/video - Cópia/vid_et4000.h | 4 - backup code/video - Cópia/vid_et4000w32.c | 1392 --- backup code/video - Cópia/vid_et4000w32.h | 7 - backup code/video - Cópia/vid_et4000w32i.c | 427 - backup code/video - Cópia/vid_genius.c | 655 -- backup code/video - Cópia/vid_genius.h | 1 - backup code/video - Cópia/vid_hercules.c | 427 - backup code/video - Cópia/vid_hercules.h | 4 - backup code/video - Cópia/vid_herculesplus.c | 739 -- backup code/video - Cópia/vid_herculesplus.h | 4 - backup code/video - Cópia/vid_icd2061.c | 80 - backup code/video - Cópia/vid_icd2061.h | 17 - backup code/video - Cópia/vid_ics2595.c | 73 - backup code/video - Cópia/vid_ics2595.h | 15 - backup code/video - Cópia/vid_incolor.c | 1083 --- backup code/video - Cópia/vid_incolor.h | 4 - backup code/video - Cópia/vid_mda.c | 380 - backup code/video - Cópia/vid_mda.h | 4 - backup code/video - Cópia/vid_nv_riva128.c | 3711 -------- backup code/video - Cópia/vid_nv_riva128.h | 3 - backup code/video - Cópia/vid_nvidia.c | 965 -- backup code/video - Cópia/vid_nvidia.h | 1 - backup code/video - Cópia/vid_oak_oti.c | 423 - backup code/video - Cópia/vid_oak_oti.h | 7 - backup code/video - Cópia/vid_paradise.c | 617 -- backup code/video - Cópia/vid_paradise.h | 9 - backup code/video - Cópia/vid_s3.c | 3245 ------- backup code/video - Cópia/vid_s3.h | 33 - backup code/video - Cópia/vid_s3_virge.c | 4328 --------- backup code/video - Cópia/vid_s3_virge.h | 11 - .../video - Cópia/vid_sc1502x_ramdac.c | 111 - .../video - Cópia/vid_sc1502x_ramdac.h | 11 - backup code/video - Cópia/vid_sdac_ramdac.c | 183 - backup code/video - Cópia/vid_sdac_ramdac.h | 19 - backup code/video - Cópia/vid_stg_ramdac.c | 181 - backup code/video - Cópia/vid_stg_ramdac.h | 14 - backup code/video - Cópia/vid_svga.c | 1353 --- backup code/video - Cópia/vid_svga.h | 205 - backup code/video - Cópia/vid_svga_render.c | 934 -- backup code/video - Cópia/vid_svga_render.h | 54 - backup code/video - Cópia/vid_table.c | 427 - backup code/video - Cópia/vid_tgui9440.c | 1796 ---- backup code/video - Cópia/vid_tgui9440.h | 6 - backup code/video - Cópia/vid_ti_cf62011.c | 312 - backup code/video - Cópia/vid_ti_cf62011.h | 4 - .../video - Cópia/vid_tkd8001_ramdac.c | 80 - .../video - Cópia/vid_tkd8001_ramdac.h | 11 - backup code/video - Cópia/vid_tvga.c | 381 - backup code/video - Cópia/vid_tvga.h | 4 - backup code/video - Cópia/vid_vga.c | 242 - backup code/video - Cópia/vid_vga.h | 8 - backup code/video - Cópia/vid_voodoo.c | 7888 ----------------- backup code/video - Cópia/vid_voodoo.h | 1 - .../video - Cópia/vid_voodoo_codegen_x86-64.h | 3349 ------- .../video - Cópia/vid_voodoo_codegen_x86.h | 3335 ------- backup code/video - Cópia/vid_voodoo_dither.h | 5136 ----------- backup code/video - Cópia/vid_wy700.c | 1021 --- backup code/video - Cópia/vid_wy700.h | 1 - backup code/video - Cópia/video.c | 766 -- backup code/video - Cópia/video.h | 268 - backup code/video/vid_cl54xx - Cópia.c | 2685 ------ backup code/video/vid_svga_render - Cópia.c | 967 -- backup code/win/Makefile - Cópia.mingw | 699 -- backup code/win/win_cdrom - Cópia.c | 154 - backup code/win/win_new_floppy - Cópia.c | 711 -- backup code/win/win_settings - Cópia.c | 4443 ---------- backup code/win/win_stbar - Cópia.c | 1123 --- 122 files changed, 96149 deletions(-) delete mode 100644 backup code/config - Cópia.c delete mode 100644 backup code/disk/hdc_esdi_mfm.c delete mode 100644 backup code/disk/hdc_ide - Cópia.c delete mode 100644 backup code/disk/zip - Cópia.c delete mode 100644 backup code/disk/zip - Cópia.h delete mode 100644 backup code/dma.c.old delete mode 100644 backup code/dma.h.old delete mode 100644 backup code/intel_piix - Cópia.c delete mode 100644 backup code/keyboard_at.c.old delete mode 100644 backup code/mouse_bus - Cópia (2).c delete mode 100644 backup code/mouse_bus - Cópia (3).c delete mode 100644 backup code/mouse_bus - Cópia (4).c delete mode 100644 backup code/mouse_bus - Cópia 2.c delete mode 100644 backup code/mouse_bus - Cópia.c delete mode 100644 backup code/mouse_bus_good.c delete mode 100644 backup code/mouse_bus_x.c delete mode 100644 backup code/network/net_pcap - Cópia.c delete mode 100644 backup code/pc - Cópia.c delete mode 100644 backup code/scsi/scsi - Cópia (2).h delete mode 100644 backup code/scsi/scsi - Cópia.c delete mode 100644 backup code/scsi/scsi - Cópia.h delete mode 100644 backup code/scsi/scsi_device - Cópia (2).c delete mode 100644 backup code/scsi/scsi_device - Cópia.c delete mode 100644 backup code/scsi/scsi_device - Cópia.h delete mode 100644 backup code/scsi/scsi_disk - Cópia.c delete mode 100644 backup code/scsi/scsi_disk - Cópia.h delete mode 100644 backup code/scsi/scsi_null.c delete mode 100644 backup code/video - Cópia/vid_ati18800.c delete mode 100644 backup code/video - Cópia/vid_ati18800.h delete mode 100644 backup code/video - Cópia/vid_ati28800.c delete mode 100644 backup code/video - Cópia/vid_ati28800.h delete mode 100644 backup code/video - Cópia/vid_ati68860_ramdac.c delete mode 100644 backup code/video - Cópia/vid_ati68860_ramdac.h delete mode 100644 backup code/video - Cópia/vid_ati_eeprom.c delete mode 100644 backup code/video - Cópia/vid_ati_eeprom.h delete mode 100644 backup code/video - Cópia/vid_ati_mach64.c delete mode 100644 backup code/video - Cópia/vid_ati_mach64.h delete mode 100644 backup code/video - Cópia/vid_bt485_ramdac.c delete mode 100644 backup code/video - Cópia/vid_bt485_ramdac.h delete mode 100644 backup code/video - Cópia/vid_cga.c delete mode 100644 backup code/video - Cópia/vid_cga.h delete mode 100644 backup code/video - Cópia/vid_cga_comp.c delete mode 100644 backup code/video - Cópia/vid_cga_comp.h delete mode 100644 backup code/video - Cópia/vid_cl54xx - Cópia.c delete mode 100644 backup code/video - Cópia/vid_cl54xx.c delete mode 100644 backup code/video - Cópia/vid_cl54xx.h delete mode 100644 backup code/video - Cópia/vid_colorplus.c delete mode 100644 backup code/video - Cópia/vid_colorplus.h delete mode 100644 backup code/video - Cópia/vid_compaq_cga.c delete mode 100644 backup code/video - Cópia/vid_compaq_cga.h delete mode 100644 backup code/video - Cópia/vid_ega.c delete mode 100644 backup code/video - Cópia/vid_ega.h delete mode 100644 backup code/video - Cópia/vid_ega_render.c delete mode 100644 backup code/video - Cópia/vid_ega_render.h delete mode 100644 backup code/video - Cópia/vid_et4000.c delete mode 100644 backup code/video - Cópia/vid_et4000.h delete mode 100644 backup code/video - Cópia/vid_et4000w32.c delete mode 100644 backup code/video - Cópia/vid_et4000w32.h delete mode 100644 backup code/video - Cópia/vid_et4000w32i.c delete mode 100644 backup code/video - Cópia/vid_genius.c delete mode 100644 backup code/video - Cópia/vid_genius.h delete mode 100644 backup code/video - Cópia/vid_hercules.c delete mode 100644 backup code/video - Cópia/vid_hercules.h delete mode 100644 backup code/video - Cópia/vid_herculesplus.c delete mode 100644 backup code/video - Cópia/vid_herculesplus.h delete mode 100644 backup code/video - Cópia/vid_icd2061.c delete mode 100644 backup code/video - Cópia/vid_icd2061.h delete mode 100644 backup code/video - Cópia/vid_ics2595.c delete mode 100644 backup code/video - Cópia/vid_ics2595.h delete mode 100644 backup code/video - Cópia/vid_incolor.c delete mode 100644 backup code/video - Cópia/vid_incolor.h delete mode 100644 backup code/video - Cópia/vid_mda.c delete mode 100644 backup code/video - Cópia/vid_mda.h delete mode 100644 backup code/video - Cópia/vid_nv_riva128.c delete mode 100644 backup code/video - Cópia/vid_nv_riva128.h delete mode 100644 backup code/video - Cópia/vid_nvidia.c delete mode 100644 backup code/video - Cópia/vid_nvidia.h delete mode 100644 backup code/video - Cópia/vid_oak_oti.c delete mode 100644 backup code/video - Cópia/vid_oak_oti.h delete mode 100644 backup code/video - Cópia/vid_paradise.c delete mode 100644 backup code/video - Cópia/vid_paradise.h delete mode 100644 backup code/video - Cópia/vid_s3.c delete mode 100644 backup code/video - Cópia/vid_s3.h delete mode 100644 backup code/video - Cópia/vid_s3_virge.c delete mode 100644 backup code/video - Cópia/vid_s3_virge.h delete mode 100644 backup code/video - Cópia/vid_sc1502x_ramdac.c delete mode 100644 backup code/video - Cópia/vid_sc1502x_ramdac.h delete mode 100644 backup code/video - Cópia/vid_sdac_ramdac.c delete mode 100644 backup code/video - Cópia/vid_sdac_ramdac.h delete mode 100644 backup code/video - Cópia/vid_stg_ramdac.c delete mode 100644 backup code/video - Cópia/vid_stg_ramdac.h delete mode 100644 backup code/video - Cópia/vid_svga.c delete mode 100644 backup code/video - Cópia/vid_svga.h delete mode 100644 backup code/video - Cópia/vid_svga_render.c delete mode 100644 backup code/video - Cópia/vid_svga_render.h delete mode 100644 backup code/video - Cópia/vid_table.c delete mode 100644 backup code/video - Cópia/vid_tgui9440.c delete mode 100644 backup code/video - Cópia/vid_tgui9440.h delete mode 100644 backup code/video - Cópia/vid_ti_cf62011.c delete mode 100644 backup code/video - Cópia/vid_ti_cf62011.h delete mode 100644 backup code/video - Cópia/vid_tkd8001_ramdac.c delete mode 100644 backup code/video - Cópia/vid_tkd8001_ramdac.h delete mode 100644 backup code/video - Cópia/vid_tvga.c delete mode 100644 backup code/video - Cópia/vid_tvga.h delete mode 100644 backup code/video - Cópia/vid_vga.c delete mode 100644 backup code/video - Cópia/vid_vga.h delete mode 100644 backup code/video - Cópia/vid_voodoo.c delete mode 100644 backup code/video - Cópia/vid_voodoo.h delete mode 100644 backup code/video - Cópia/vid_voodoo_codegen_x86-64.h delete mode 100644 backup code/video - Cópia/vid_voodoo_codegen_x86.h delete mode 100644 backup code/video - Cópia/vid_voodoo_dither.h delete mode 100644 backup code/video - Cópia/vid_wy700.c delete mode 100644 backup code/video - Cópia/vid_wy700.h delete mode 100644 backup code/video - Cópia/video.c delete mode 100644 backup code/video - Cópia/video.h delete mode 100644 backup code/video/vid_cl54xx - Cópia.c delete mode 100644 backup code/video/vid_svga_render - Cópia.c delete mode 100644 backup code/win/Makefile - Cópia.mingw delete mode 100644 backup code/win/win_cdrom - Cópia.c delete mode 100644 backup code/win/win_new_floppy - Cópia.c delete mode 100644 backup code/win/win_settings - Cópia.c delete mode 100644 backup code/win/win_stbar - Cópia.c diff --git a/backup code/config - Cópia.c b/backup code/config - Cópia.c deleted file mode 100644 index 9904236a4..000000000 --- a/backup code/config - Cópia.c +++ /dev/null @@ -1,2174 +0,0 @@ -/* - * 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. - * - * Configuration file handler. - * - * Version: @(#)config.c 1.0.48 2018/05/25 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * Overdoze, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - * - * NOTE: Forcing config files to be in Unicode encoding breaks - * it on Windows XP, and possibly also Vista. Use the - * -DANSI_CFG for use on these systems. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "cpu/cpu.h" -#include "device.h" -#include "nvr.h" -#include "config.h" -#include "lpt.h" -#include "disk/hdd.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "disk/zip.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" -#include "game/gameport.h" -#include "machine/machine.h" -#include "mouse.h" -#include "network/network.h" -#include "scsi/scsi.h" -#include "cdrom/cdrom.h" -#include "sound/sound.h" -#include "sound/midi.h" -#include "sound/snd_dbopl.h" -#include "sound/snd_mpu401.h" -#include "sound/snd_opl.h" -#include "sound/sound.h" -#include "video/video.h" -#include "plat.h" -#include "plat_midi.h" -#include "ui.h" - - -typedef struct _list_ { - struct _list_ *next; -} list_t; - -typedef struct { - list_t list; - - char name[128]; - - list_t entry_head; -} section_t; - -typedef struct { - list_t list; - - char name[128]; - char data[256]; - wchar_t wdata[512]; -} entry_t; - -#define list_add(new, head) { \ - list_t *next = head; \ - \ - while (next->next != NULL) \ - next = next->next; \ - \ - (next)->next = new; \ - (new)->next = NULL; \ -} - -#define list_delete(old, head) { \ - list_t *next = head; \ - \ - while ((next)->next != old) { \ - next = (next)->next; \ - } \ - \ - (next)->next = (old)->next; \ -} - - -static list_t config_head; - - -#ifdef ENABLE_CONFIG_LOG -int config_do_log = ENABLE_CONFIG_LOG; -#endif - - -static void -config_log(const char *format, ...) -{ -#ifdef ENABLE_CONFIG_LOG - va_list ap; - - if (config_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -static section_t * -find_section(char *name) -{ - section_t *sec; - char blank[] = ""; - - sec = (section_t *)config_head.next; - if (name == NULL) - name = blank; - - while (sec != NULL) { - if (! strncmp(sec->name, name, sizeof(sec->name))) - return(sec); - - sec = (section_t *)sec->list.next; - } - - return(NULL); -} - - -static entry_t * -find_entry(section_t *section, char *name) -{ - entry_t *ent; - - ent = (entry_t *)section->entry_head.next; - - while (ent != NULL) { - if (! strncmp(ent->name, name, sizeof(ent->name))) - return(ent); - - ent = (entry_t *)ent->list.next; - } - - return(NULL); -} - - -static int -entries_num(section_t *section) -{ - entry_t *ent; - int i = 0; - - ent = (entry_t *)section->entry_head.next; - - while (ent != NULL) { - if (strlen(ent->name) > 0) i++; - - ent = (entry_t *)ent->list.next; - } - - return(i); -} - - -static void -delete_section_if_empty(char *head) -{ - section_t *section; - - section = find_section(head); - if (section == NULL) return; - - if (entries_num(section) == 0) { - list_delete(§ion->list, &config_head); - free(section); - } -} - - -static section_t * -create_section(char *name) -{ - section_t *ns = malloc(sizeof(section_t)); - - memset(ns, 0x00, sizeof(section_t)); - strncpy(ns->name, name, sizeof(ns->name)); - list_add(&ns->list, &config_head); - - return(ns); -} - - -static entry_t * -create_entry(section_t *section, char *name) -{ - entry_t *ne = malloc(sizeof(entry_t)); - - memset(ne, 0x00, sizeof(entry_t)); - strncpy(ne->name, name, sizeof(ne->name)); - list_add(&ne->list, §ion->entry_head); - - return(ne); -} - - -#if 0 -static void -config_free(void) -{ - section_t *sec, *ns; - entry_t *ent; - - sec = (section_t *)config_head.next; - while (sec != NULL) { - ns = (section_t *)sec->list.next; - ent = (entry_t *)sec->entry_head.next; - - while (ent != NULL) { - entry_t *nent = (entry_t *)ent->list.next; - - free(ent); - ent = nent; - } - - free(sec); - sec = ns; - } -} -#endif - - -/* Read and parse the configuration file into memory. */ -static int -config_read(wchar_t *fn) -{ - char sname[128], ename[128]; - wchar_t buff[1024]; - section_t *sec, *ns; - entry_t *ne; - int c, d; - FILE *f; - -#if defined(ANSI_CFG) || !defined(_WIN32) - f = plat_fopen(fn, L"rt"); -#else - f = plat_fopen(fn, L"rt, ccs=UNICODE"); -#endif - if (f == NULL) return(0); - - sec = malloc(sizeof(section_t)); - memset(sec, 0x00, sizeof(section_t)); - memset(&config_head, 0x00, sizeof(list_t)); - list_add(&sec->list, &config_head); - - while (1) { - memset(buff, 0x00, sizeof(buff)); - fgetws(buff, sizeof_w(buff), f); - if (feof(f)) break; - - /* Make sure there are no stray newlines or hard-returns in there. */ - if (buff[wcslen(buff)-1] == L'\n') buff[wcslen(buff)-1] = L'\0'; - if (buff[wcslen(buff)-1] == L'\r') buff[wcslen(buff)-1] = L'\0'; - - /* Skip any leading whitespace. */ - c = 0; - while ((buff[c] == L' ') || (buff[c] == L'\t')) - c++; - - /* Skip empty lines. */ - if (buff[c] == L'\0') continue; - - /* Skip lines that (only) have a comment. */ - if ((buff[c] == L'#') || (buff[c] == L';')) continue; - - if (buff[c] == L'[') { /*Section*/ - c++; - d = 0; - while (buff[c] != L']' && buff[c]) - wctomb(&(sname[d++]), buff[c++]); - sname[d] = L'\0'; - - /* Is the section name properly terminated? */ - if (buff[c] != L']') continue; - - /* Create a new section and insert it. */ - ns = malloc(sizeof(section_t)); - memset(ns, 0x00, sizeof(section_t)); - strncpy(ns->name, sname, sizeof(ns->name)); - list_add(&ns->list, &config_head); - - /* New section is now the current one. */ - sec = ns; - continue; - } - - /* Get the variable name. */ - d = 0; - while ((buff[c] != L'=') && (buff[c] != L' ') && buff[c]) - wctomb(&(ename[d++]), buff[c++]); - ename[d] = L'\0'; - - /* Skip incomplete lines. */ - if (buff[c] == L'\0') continue; - - /* Look for =, skip whitespace. */ - while ((buff[c] == L'=' || buff[c] == L' ') && buff[c]) - c++; - - /* Skip incomplete lines. */ - if (buff[c] == L'\0') continue; - - /* This is where the value part starts. */ - d = c; - - /* Allocate a new variable entry.. */ - ne = malloc(sizeof(entry_t)); - memset(ne, 0x00, sizeof(entry_t)); - strncpy(ne->name, ename, sizeof(ne->name)); - wcsncpy(ne->wdata, &buff[d], sizeof_w(ne->wdata)-1); - ne->wdata[sizeof_w(ne->wdata)-1] = L'\0'; - wcstombs(ne->data, ne->wdata, sizeof(ne->data)); - ne->data[sizeof(ne->data)-1] = '\0'; - - /* .. and insert it. */ - list_add(&ne->list, &sec->entry_head); - } - - (void)fclose(f); - - if (do_dump_config) - config_dump(); - - return(1); -} - - -/* - * Write the in-memory configuration to disk. - * This is a public function, because the Settings UI - * want to directly write the configuration after it - * has changed it. - */ -void -config_write(wchar_t *fn) -{ - wchar_t wtemp[512]; - section_t *sec; - FILE *f; - int fl = 0; - -#if defined(ANSI_CFG) || !defined(_WIN32) - f = plat_fopen(fn, L"wt"); -#else - f = plat_fopen(fn, L"wt, ccs=UNICODE"); -#endif - if (f == NULL) return; - - sec = (section_t *)config_head.next; - while (sec != NULL) { - entry_t *ent; - - if (sec->name[0]) { - mbstowcs(wtemp, sec->name, strlen(sec->name)+1); - if (fl) - fwprintf(f, L"\n[%ls]\n", wtemp); - else - fwprintf(f, L"[%ls]\n", wtemp); - fl++; - } - - ent = (entry_t *)sec->entry_head.next; - while (ent != NULL) { - if (ent->name[0] != '\0') { - mbstowcs(wtemp, ent->name, sizeof_w(wtemp)); - if (ent->wdata[0] == L'\0') - fwprintf(f, L"%ls = \n", wtemp); - else - fwprintf(f, L"%ls = %ls\n", wtemp, ent->wdata); - fl++; - } - - ent = (entry_t *)ent->list.next; - } - - sec = (section_t *)sec->list.next; - } - - (void)fclose(f); -} - - -#if NOT_USED -static void -config_new(void) -{ -#if defined(ANSI_CFG) || !defined(_WIN32) - FILE *f = _wfopen(config_file, L"wt"); -#else - FILE *f = _wfopen(config_file, L"wt, ccs=UNICODE"); -#endif - - if (file != NULL) - (void)fclose(f); -} -#endif - - -/* Load "General" section. */ -static void -load_general(void) -{ - char *cat = "General"; - char temp[512]; - char *p; - - vid_resize = !!config_get_int(cat, "vid_resize", 0); - - memset(temp, '\0', sizeof(temp)); - p = config_get_string(cat, "vid_renderer", "default"); - vid_api = plat_vidapi(p); - config_delete_var(cat, "vid_api"); - - video_fullscreen_scale = config_get_int(cat, "video_fullscreen_scale", 0); - - video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 0); - - force_43 = !!config_get_int(cat, "force_43", 0); - scale = config_get_int(cat, "scale", 1); - if (scale > 3) - scale = 3; - - enable_overscan = !!config_get_int(cat, "enable_overscan", 0); - vid_cga_contrast = !!config_get_int(cat, "vid_cga_contrast", 0); - video_grayscale = config_get_int(cat, "video_grayscale", 0); - video_graytype = config_get_int(cat, "video_graytype", 0); - - rctrl_is_lalt = config_get_int(cat, "rctrl_is_lalt", 0); - update_icons = config_get_int(cat, "update_icons", 1); - - window_remember = config_get_int(cat, "window_remember", 0); - if (window_remember) { - p = config_get_string(cat, "window_coordinates", NULL); - if (p == NULL) - p = "0, 0, 0, 0"; - sscanf(p, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); - } else { - config_delete_var(cat, "window_remember"); - config_delete_var(cat, "window_coordinates"); - - window_w = window_h = window_x = window_y = 0; - } - - sound_gain = config_get_int(cat, "sound_gain", 0); - -#ifdef USE_LANGUAGE - /* - * Currently, 86Box is English (US) only, but in the future - * (version 3.0 at the earliest) other languages will be - * added, therefore it is better to future-proof the code. - */ - plat_langid = config_get_hex16(cat, "language", 0x0409); -#endif -} - - -/* Load "Machine" section. */ -static void -load_machine(void) -{ - char *cat = "Machine"; - char *p; - - p = config_get_string(cat, "machine", NULL); - if (p != NULL) - machine = machine_get_machine_from_internal_name(p); - else - machine = 0; - if (machine >= machine_count()) - machine = machine_count() - 1; - - /* This is for backwards compatibility. */ - p = config_get_string(cat, "model", NULL); - if (p != NULL) { - /* Detect the old model typos and fix them. */ - if (! strcmp(p, "p55r2p4")) { - machine = machine_get_machine_from_internal_name("p55t2p4"); - } else { - machine = machine_get_machine_from_internal_name(p); - } - config_delete_var(cat, "model"); - } - if (machine >= machine_count()) - machine = machine_count() - 1; - - romset = machine_getromset(); - cpu_manufacturer = config_get_int(cat, "cpu_manufacturer", 0); - cpu = config_get_int(cat, "cpu", 0); - cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0); - - mem_size = config_get_int(cat, "mem_size", 4096); - if (mem_size < (((machines[machine].flags & MACHINE_AT) && - (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram)) - mem_size = (((machines[machine].flags & MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram); - if (mem_size > 1048576) - mem_size = 1048576; - - cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0); - - enable_external_fpu = !!config_get_int(cat, "cpu_enable_fpu", 0); - - enable_sync = !!config_get_int(cat, "enable_sync", 1); - - /* Remove this after a while.. */ - config_delete_var(cat, "nvr_path"); -} - - -/* Load "Video" section. */ -static void -load_video(void) -{ - char *cat = "Video"; - char *p; - - if (machines[machine].fixed_gfxcard) { - config_delete_var(cat, "gfxcard"); - gfxcard = GFX_INTERNAL; - } else { - p = config_get_string(cat, "gfxcard", NULL); - if (p == NULL) { - if (machines[machine].flags & MACHINE_VIDEO) { - p = (char *)malloc((strlen("internal")+1)*sizeof(char)); - strcpy(p, "internal"); - } else { - p = (char *)malloc((strlen("none")+1)*sizeof(char)); - strcpy(p, "none"); - } - } - gfxcard = video_get_video_from_internal_name(p); - } - - voodoo_enabled = !!config_get_int(cat, "voodoo", 0); -} - - -/* Load "Input Devices" section. */ -static void -load_input_devices(void) -{ - char *cat = "Input devices"; - char temp[512]; - int c, d; - char *p; - - p = config_get_string(cat, "mouse_type", NULL); - if (p != NULL) - mouse_type = mouse_get_from_internal_name(p); - else - mouse_type = 0; - - joystick_type = config_get_int(cat, "joystick_type", 7); - - for (c=0; c max_spt) - hdd[c].spt = max_spt; - if (hdd[c].hpc > max_hpc) - hdd[c].hpc = max_hpc; - if (hdd[c].tracks > max_tracks) - hdd[c].tracks = max_tracks; - - /* MFM/RLL */ - sprintf(temp, "hdd_%02i_mfm_channel", c+1); - if (hdd[c].bus == HDD_BUS_MFM) - hdd[c].mfm_channel = !!config_get_int(cat, temp, c & 1); - else - config_delete_var(cat, temp); - - /* XTA */ - sprintf(temp, "hdd_%02i_xta_channel", c+1); - if (hdd[c].bus == HDD_BUS_XTA) - hdd[c].xta_channel = !!config_get_int(cat, temp, c & 1); - else - config_delete_var(cat, temp); - - /* ESDI */ - sprintf(temp, "hdd_%02i_esdi_channel", c+1); - if (hdd[c].bus == HDD_BUS_ESDI) - hdd[c].esdi_channel = !!config_get_int(cat, temp, c & 1); - else - config_delete_var(cat, temp); - - /* IDE */ - // FIXME: Remove in a month. - sprintf(temp, "hdd_%02i_xtide_channel", c+1); - if (hdd[c].bus == HDD_BUS_IDE) - hdd[c].ide_channel = !!config_get_int(cat, temp, c & 1); - else - config_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_ide_channel", c+1); - if (hdd[c].bus == HDD_BUS_IDE) { - sprintf(tmp2, "%01u:%01u", c>>1, c&1); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%01u", &board, &dev); - board &= 3; - dev &= 1; - hdd[c].ide_channel = (board<<1) + dev; - - if (hdd[c].ide_channel > 7) - hdd[c].ide_channel = 7; - } else { - config_delete_var(cat, temp); - } - - /* SCSI */ - sprintf(temp, "hdd_%02i_scsi_location", c+1); - if (hdd[c].bus == HDD_BUS_SCSI) { - sprintf(tmp2, "%02u:%02u", c, 0); - p = config_get_string(cat, temp, tmp2); - - sscanf(p, "%02i:%02i", - (int *)&hdd[c].scsi_id, (int *)&hdd[c].scsi_lun); - - if (hdd[c].scsi_id > 15) - hdd[c].scsi_id = 15; - if (hdd[c].scsi_lun > 7) - hdd[c].scsi_lun = 7; - } else { - config_delete_var(cat, temp); - } - - memset(hdd[c].fn, 0x00, sizeof(hdd[c].fn)); - memset(hdd[c].prev_fn, 0x00, sizeof(hdd[c].prev_fn)); - sprintf(temp, "hdd_%02i_fn", c+1); - wp = config_get_wstring(cat, temp, L""); - -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the CFG path. Just strip - * that off for now... - */ - wcsncpy(hdd[c].fn, &wp[wcslen(usr_path)], sizeof_w(hdd[c].fn)); - } else -#endif - wcsncpy(hdd[c].fn, wp, sizeof_w(hdd[c].fn)); - - /* If disk is empty or invalid, mark it for deletion. */ - if (! hdd_is_valid(c)) { - sprintf(temp, "hdd_%02i_parameters", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_preide_channels", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_ide_channels", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_scsi_location", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_fn", c+1); - config_delete_var(cat, temp); - } - - sprintf(temp, "hdd_%02i_mfm_channel", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_ide_channel", c+1); - config_delete_var(cat, temp); - } -} - - -/* Load "Floppy Drives" section. */ -static void -load_floppy_drives(void) -{ - char *cat = "Floppy drives"; - char temp[512], *p; - wchar_t *wp; - int c; - - for (c=0; c 13) - fdd_set_type(c, 13); - - sprintf(temp, "fdd_%02i_fn", c + 1); - wp = config_get_wstring(cat, temp, L""); - -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c])); - } else -#endif - wcsncpy(floppyfns[c], wp, sizeof_w(floppyfns[c])); - - /* if (*wp != L'\0') - config_log("Floppy%d: %ls\n", c, floppyfns[c]); */ - sprintf(temp, "fdd_%02i_writeprot", c+1); - ui_writeprot[c] = !!config_get_int(cat, temp, 0); - sprintf(temp, "fdd_%02i_turbo", c + 1); - fdd_set_turbo(c, !!config_get_int(cat, temp, 0)); - sprintf(temp, "fdd_%02i_check_bpb", c+1); - fdd_set_check_bpb(c, !!config_get_int(cat, temp, 1)); - - /* Check whether each value is default, if yes, delete it so that only non-default values will later be saved. */ - if (fdd_get_type(c) == ((c < 2) ? 2 : 0)) { - sprintf(temp, "fdd_%02i_type", c+1); - config_delete_var(cat, temp); - } - if (wcslen(floppyfns[c]) == 0) { - sprintf(temp, "fdd_%02i_fn", c+1); - config_delete_var(cat, temp); - } - if (ui_writeprot[c] == 0) { - sprintf(temp, "fdd_%02i_writeprot", c+1); - config_delete_var(cat, temp); - } - if (fdd_get_turbo(c) == 0) { - sprintf(temp, "fdd_%02i_turbo", c+1); - config_delete_var(cat, temp); - } - if (fdd_get_check_bpb(c) == 1) { - sprintf(temp, "fdd_%02i_check_bpb", c+1); - config_delete_var(cat, temp); - } - } -} - - -/* Load "Other Removable Devices" section. */ -static void -load_other_removable_devices(void) -{ - char *cat = "Other removable devices"; - char temp[512], tmp2[512], *p; - char s[512]; - unsigned int board = 0, dev = 0; - wchar_t *wp; - int c; - - memset(temp, 0x00, sizeof(temp)); - for (c=0; c>1, (c+2)&1); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%01u", &board, &dev); - board &= 3; - dev &= 1; - cdrom_drives[c].ide_channel = (board<<1)+dev; - - if (cdrom_drives[c].ide_channel > 7) - cdrom_drives[c].ide_channel = 7; - } else { - sprintf(temp, "cdrom_%02i_scsi_location", c+1); - if (cdrom_drives[c].bus_type == CDROM_BUS_SCSI) { - sprintf(tmp2, "%02u:%02u", c+2, 0); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%02u:%02u", - &cdrom_drives[c].scsi_device_id, - &cdrom_drives[c].scsi_device_lun); - - if (cdrom_drives[c].scsi_device_id > 15) - cdrom_drives[c].scsi_device_id = 15; - if (cdrom_drives[c].scsi_device_lun > 7) - cdrom_drives[c].scsi_device_lun = 7; - } else { - config_delete_var(cat, temp); - } - } - - sprintf(temp, "cdrom_%02i_image_path", c+1); - wp = config_get_wstring(cat, temp, L""); - -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(cdrom_image[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom_image[c].image_path)); - } else -#endif - wcsncpy(cdrom_image[c].image_path, wp, sizeof_w(cdrom_image[c].image_path)); - - if (cdrom_drives[c].host_drive < 'A') - cdrom_drives[c].host_drive = 0; - - if ((cdrom_drives[c].host_drive == 0x200) && - (wcslen(cdrom_image[c].image_path) == 0)) - cdrom_drives[c].host_drive = 0; - - /* If the CD-ROM is disabled, delete all its variables. */ - if (cdrom_drives[c].bus_type == CDROM_BUS_DISABLED) { - sprintf(temp, "cdrom_%02i_host_drive", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "cdrom_%02i_parameters", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "cdrom_%02i_ide_channel", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "cdrom_%02i_scsi_location", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "cdrom_%02i_image_path", c+1); - config_delete_var(cat, temp); - } - - sprintf(temp, "cdrom_%02i_iso_path", c+1); - config_delete_var(cat, temp); - } - - memset(temp, 0x00, sizeof(temp)); - for (c=0; c>1, (c+2)&1); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%01u", &board, &dev); - board &= 3; - dev &= 1; - zip_drives[c].ide_channel = (board<<1)+dev; - - if (zip_drives[c].ide_channel > 7) - zip_drives[c].ide_channel = 7; - } else { - sprintf(temp, "zip_%02i_scsi_location", c+1); - if (zip_drives[c].bus_type == CDROM_BUS_SCSI) { - sprintf(tmp2, "%02u:%02u", c+2, 0); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%02u:%02u", - &zip_drives[c].scsi_device_id, - &zip_drives[c].scsi_device_lun); - - if (zip_drives[c].scsi_device_id > 15) - zip_drives[c].scsi_device_id = 15; - if (zip_drives[c].scsi_device_lun > 7) - zip_drives[c].scsi_device_lun = 7; - } else { - config_delete_var(cat, temp); - } - } - - sprintf(temp, "zip_%02i_image_path", c+1); - wp = config_get_wstring(cat, temp, L""); - -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(zip_drives[c].image_path, &wp[wcslen(usr_path)], sizeof_w(zip_drives[c].image_path)); - } else -#endif - wcsncpy(zip_drives[c].image_path, wp, sizeof_w(zip_drives[c].image_path)); - - /* If the CD-ROM is disabled, delete all its variables. */ - if (zip_drives[c].bus_type == ZIP_BUS_DISABLED) { - sprintf(temp, "zip_%02i_host_drive", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "zip_%02i_parameters", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "zip_%02i_ide_channel", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "zip_%02i_scsi_location", c+1); - config_delete_var(cat, temp); - - sprintf(temp, "zip_%02i_image_path", c+1); - config_delete_var(cat, temp); - } - - sprintf(temp, "zip_%02i_iso_path", c+1); - config_delete_var(cat, temp); - } -} - - -/* Load the specified or a default configuration file. */ -void -config_load(void) -{ - int i; - - config_log("Loading config file '%ls'..\n", cfg_path); - - memset(hdd, 0, sizeof(hard_disk_t)); - memset(cdrom_drives, 0, sizeof(cdrom_drive_t) * CDROM_NUM); - memset(cdrom_image, 0, sizeof(cdrom_image_t) * CDROM_NUM); -#ifdef USE_IOCTL - memset(cdrom_ioctl, 0, sizeof(cdrom_ioctl_t) * CDROM_NUM); -#endif - memset(zip_drives, 0, sizeof(zip_drive_t)); - - if (! config_read(cfg_path)) { - cpu = 0; -#ifdef USE_LANGUAGE - plat_langid = 0x0409; -#endif - scale = 1; - machine = machine_get_machine_from_internal_name("ibmpc"); - gfxcard = GFX_CGA; - vid_api = plat_vidapi("default"); - enable_sync = 1; - joystick_type = 7; - if (hdc_name) { - free(hdc_name); - hdc_name = NULL; - } - hdc_name = (char *) malloc((strlen("none")+1) * sizeof(char)); - strcpy(hdc_name, "none"); - serial_enabled[0] = 1; - serial_enabled[1] = 1; - lpt_enabled = 1; - for (i = 0; i < FDD_NUM; i++) { - if (i < 2) - fdd_set_type(i, 2); - else - fdd_set_type(i, 0); - - fdd_set_turbo(i, 0); - fdd_set_check_bpb(i, 1); - } - mem_size = 640; - opl_type = 0; - - config_log("Config file not present or invalid!\n"); - return; - } - - load_general(); /* General */ - load_machine(); /* Machine */ - load_video(); /* Video */ - load_input_devices(); /* Input devices */ - load_sound(); /* Sound */ - load_network(); /* Network */ - load_ports(); /* Ports (COM & LPT) */ - load_other_peripherals(); /* Other peripherals */ - load_hard_disks(); /* Hard disks */ - load_floppy_drives(); /* Floppy drives */ - load_other_removable_devices(); /* Other removable devices */ - - /* Mark the configuration as changed. */ - config_changed = 1; - - config_log("Config loaded.\n\n"); -} - - -/* Save "General" section. */ -static void -save_general(void) -{ - char *cat = "General"; - char temp[512]; - - char *va_name; - - config_set_int(cat, "vid_resize", vid_resize); - if (vid_resize == 0) - config_delete_var(cat, "vid_resize"); - - va_name = plat_vidapi_name(vid_api); - if (!strcmp(va_name, "default")) { - config_delete_var(cat, "vid_renderer"); - } else { - config_set_string(cat, "vid_renderer", va_name); - } - - if (video_fullscreen_scale == 0) - config_delete_var(cat, "video_fullscreen_scale"); - else - config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); - - if (video_fullscreen_first == 0) - config_delete_var(cat, "video_fullscreen_first"); - else - config_set_int(cat, "video_fullscreen_first", video_fullscreen_first); - - if (force_43 == 0) - config_delete_var(cat, "force_43"); - else - config_set_int(cat, "force_43", force_43); - - if (scale == 1) - config_delete_var(cat, "scale"); - else - config_set_int(cat, "scale", scale); - - if (enable_overscan == 0) - config_delete_var(cat, "enable_overscan"); - else - config_set_int(cat, "enable_overscan", enable_overscan); - - if (vid_cga_contrast == 0) - config_delete_var(cat, "vid_cga_contrast"); - else - config_set_int(cat, "vid_cga_contrast", vid_cga_contrast); - - if (video_grayscale == 0) - config_delete_var(cat, "video_grayscale"); - else - config_set_int(cat, "video_grayscale", video_grayscale); - - if (video_graytype == 0) - config_delete_var(cat, "video_graytype"); - else - config_set_int(cat, "video_graytype", video_graytype); - - if (rctrl_is_lalt == 0) - config_delete_var(cat, "rctrl_is_lalt"); - else - config_set_int(cat, "rctrl_is_lalt", rctrl_is_lalt); - - if (update_icons == 1) - config_delete_var(cat, "update_icons"); - else - config_set_int(cat, "update_icons", update_icons); - - if (window_remember) { - config_set_int(cat, "window_remember", window_remember); - - sprintf(temp, "%i, %i, %i, %i", window_w, window_h, window_x, window_y); - config_set_string(cat, "window_coordinates", temp); - } else { - config_delete_var(cat, "window_remember"); - config_delete_var(cat, "window_coordinates"); - } - - if (sound_gain != 0) - config_set_int(cat, "sound_gain", sound_gain); - else - config_delete_var(cat, "sound_gain"); - -#ifdef USE_LANGUAGE - if (plat_langid == 0x0409) - config_delete_var(cat, "language"); - else - config_set_hex16(cat, "language", plat_langid); -#endif - - delete_section_if_empty(cat); -} - - -/* Save "Machine" section. */ -static void -save_machine(void) -{ - char *cat = "Machine"; - - config_set_string(cat, "machine", machine_get_internal_name()); - - if (cpu_manufacturer == 0) - config_delete_var(cat, "cpu_manufacturer"); - else - config_set_int(cat, "cpu_manufacturer", cpu_manufacturer); - - if (cpu == 0) - config_delete_var(cat, "cpu"); - else - config_set_int(cat, "cpu", cpu); - - if (cpu_waitstates == 0) - config_delete_var(cat, "cpu_waitstates"); - else - config_set_int(cat, "cpu_waitstates", cpu_waitstates); - - if (mem_size == 4096) - config_delete_var(cat, "mem_size"); - else - config_set_int(cat, "mem_size", mem_size); - - config_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec); - - if (enable_external_fpu == 0) - config_delete_var(cat, "cpu_enable_fpu"); - else - config_set_int(cat, "cpu_enable_fpu", enable_external_fpu); - - if (enable_sync == 1) - config_delete_var(cat, "enable_sync"); - else - config_set_int(cat, "enable_sync", enable_sync); - - delete_section_if_empty(cat); -} - - -/* Save "Video" section. */ -static void -save_video(void) -{ - char *cat = "Video"; - - config_set_string(cat, "gfxcard", - video_get_internal_name(video_old_to_new(gfxcard))); - - if (voodoo_enabled == 0) - config_delete_var(cat, "voodoo"); - else - config_set_int(cat, "voodoo", voodoo_enabled); - - delete_section_if_empty(cat); -} - - -/* Save "Input Devices" section. */ -static void -save_input_devices(void) -{ - char *cat = "Input devices"; - char temp[512], tmp2[512]; - int c, d; - - config_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type)); - - if ((joystick_type == 0) || (joystick_type == 7)) { - if (joystick_type == 7) - config_delete_var(cat, "joystick_type"); - else - config_set_int(cat, "joystick_type", joystick_type); - - for (c=0; c<16; c++) { - sprintf(tmp2, "joystick_%i_nr", c); - config_delete_var(cat, tmp2); - - for (d=0; d<16; d++) { - sprintf(tmp2, "joystick_%i_axis_%i", c, d); - config_delete_var(cat, tmp2); - } - for (d=0; d<16; d++) { - sprintf(tmp2, "joystick_%i_button_%i", c, d); - config_delete_var(cat, tmp2); - } - for (d=0; d<16; d++) { - sprintf(tmp2, "joystick_%i_pov_%i", c, d); - config_delete_var(cat, tmp2); - } - } - } else { - config_set_int(cat, "joystick_type", joystick_type); - - for (c=0; c> 1, hdd[c].ide_channel & 1); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "hdd_%02i_scsi_location", c+1); - if (! hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_SCSI)) { - config_delete_var(cat, temp); - } else { - sprintf(tmp2, "%02u:%02u", hdd[c].scsi_id, hdd[c].scsi_lun); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "hdd_%02i_fn", c+1); - if (hdd_is_valid(c) && (wcslen(hdd[c].fn) != 0)) - config_set_wstring(cat, temp, hdd[c].fn); - else - config_delete_var(cat, temp); - } - - delete_section_if_empty(cat); -} - - -/* Save "Floppy Drives" section. */ -static void -save_floppy_drives(void) -{ - char *cat = "Floppy drives"; - char temp[512]; - int c; - - for (c=0; c 'Z') && (cdrom_drives[c].host_drive != 200))) { - config_delete_var(cat, temp); - } else { - config_set_int(cat, temp, cdrom_drives[c].host_drive); - } - - sprintf(temp, "cdrom_%02i_speed", c+1); - if ((cdrom_drives[c].bus_type == 0) || (cdrom_drives[c].speed == 8)) { - config_delete_var(cat, temp); - } else { - config_set_int(cat, temp, cdrom_drives[c].speed); - } - - sprintf(temp, "cdrom_%02i_parameters", c+1); - if (cdrom_drives[c].bus_type == 0) { - config_delete_var(cat, temp); - } else { - sprintf(tmp2, "%u, %s", cdrom_drives[c].sound_on, - hdd_bus_to_string(cdrom_drives[c].bus_type, 1)); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "cdrom_%02i_ide_channel", c+1); - if (cdrom_drives[c].bus_type != CDROM_BUS_ATAPI) - config_delete_var(cat, temp); - else { - sprintf(tmp2, "%01u:%01u", cdrom_drives[c].ide_channel>>1, - cdrom_drives[c].ide_channel & 1); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "cdrom_%02i_scsi_location", c + 1); - if (cdrom_drives[c].bus_type != CDROM_BUS_SCSI) { - config_delete_var(cat, temp); - } else { - sprintf(tmp2, "%02u:%02u", cdrom_drives[c].scsi_device_id, - cdrom_drives[c].scsi_device_lun); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "cdrom_%02i_image_path", c + 1); - if ((cdrom_drives[c].bus_type == 0) || - (wcslen(cdrom_image[c].image_path) == 0)) { - config_delete_var(cat, temp); - } else { - config_set_wstring(cat, temp, cdrom_image[c].image_path); - } - } - - for (c=0; c>1, - zip_drives[c].ide_channel & 1); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "zip_%02i_scsi_location", c + 1); - if (zip_drives[c].bus_type != ZIP_BUS_SCSI) { - config_delete_var(cat, temp); - } else { - sprintf(tmp2, "%02u:%02u", zip_drives[c].scsi_device_id, - zip_drives[c].scsi_device_lun); - config_set_string(cat, temp, tmp2); - } - - sprintf(temp, "zip_%02i_image_path", c + 1); - if ((zip_drives[c].bus_type == 0) || - (wcslen(zip_drives[c].image_path) == 0)) { - config_delete_var(cat, temp); - } else { - config_set_wstring(cat, temp, zip_drives[c].image_path); - } - } - - delete_section_if_empty(cat); -} - - -void -config_save(void) -{ - save_general(); /* General */ - save_machine(); /* Machine */ - save_video(); /* Video */ - save_input_devices(); /* Input devices */ - save_sound(); /* Sound */ - save_network(); /* Network */ - save_ports(); /* Ports (COM & LPT) */ - save_other_peripherals(); /* Other peripherals */ - save_hard_disks(); /* Hard disks */ - save_floppy_drives(); /* Floppy drives */ - save_other_removable_devices(); /* Other removable devices */ - - config_write(cfg_path); -} - - -void -config_dump(void) -{ - section_t *sec; - - sec = (section_t *)config_head.next; - while (sec != NULL) { - entry_t *ent; - - if (sec->name && sec->name[0]) - config_log("[%s]\n", sec->name); - - ent = (entry_t *)sec->entry_head.next; - while (ent != NULL) { - config_log("%s = %ls\n", ent->name, ent->wdata); - - ent = (entry_t *)ent->list.next; - } - - sec = (section_t *)sec->list.next; - } -} - - -void -config_delete_var(char *head, char *name) -{ - section_t *section; - entry_t *entry; - - section = find_section(head); - if (section == NULL) return; - - entry = find_entry(section, name); - if (entry != NULL) { - list_delete(&entry->list, §ion->entry_head); - free(entry); - } -} - - -int -config_get_int(char *head, char *name, int def) -{ - section_t *section; - entry_t *entry; - int value; - - section = find_section(head); - if (section == NULL) - return(def); - - entry = find_entry(section, name); - if (entry == NULL) - return(def); - - sscanf(entry->data, "%i", &value); - - return(value); -} - - -int -config_get_hex16(char *head, char *name, int def) -{ - section_t *section; - entry_t *entry; - unsigned int value; - - section = find_section(head); - if (section == NULL) - return(def); - - entry = find_entry(section, name); - if (entry == NULL) - return(def); - - sscanf(entry->data, "%04X", &value); - - return(value); -} - - -int -config_get_hex20(char *head, char *name, int def) -{ - section_t *section; - entry_t *entry; - unsigned int value; - - section = find_section(head); - if (section == NULL) - return(def); - - entry = find_entry(section, name); - if (entry == NULL) - return(def); - - sscanf(entry->data, "%05X", &value); - - return(value); -} - - -int -config_get_mac(char *head, char *name, int def) -{ - section_t *section; - entry_t *entry; - unsigned int val0 = 0, val1 = 0, val2 = 0; - - section = find_section(head); - if (section == NULL) - return(def); - - entry = find_entry(section, name); - if (entry == NULL) - return(def); - - sscanf(entry->data, "%02x:%02x:%02x", &val0, &val1, &val2); - - return((val0 << 16) + (val1 << 8) + val2); -} - - -char * -config_get_string(char *head, char *name, char *def) -{ - section_t *section; - entry_t *entry; - - section = find_section(head); - if (section == NULL) - return(def); - - entry = find_entry(section, name); - if (entry == NULL) - return(def); - - return(entry->data); -} - - -wchar_t * -config_get_wstring(char *head, char *name, wchar_t *def) -{ - section_t *section; - entry_t *entry; - - section = find_section(head); - if (section == NULL) - return(def); - - entry = find_entry(section, name); - if (entry == NULL) - return(def); - - return(entry->wdata); -} - - -void -config_set_int(char *head, char *name, int val) -{ - section_t *section; - entry_t *ent; - - section = find_section(head); - if (section == NULL) - section = create_section(head); - - ent = find_entry(section, name); - if (ent == NULL) - ent = create_entry(section, name); - - sprintf(ent->data, "%i", val); - mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata)); -} - - -void -config_set_hex16(char *head, char *name, int val) -{ - section_t *section; - entry_t *ent; - - section = find_section(head); - if (section == NULL) - section = create_section(head); - - ent = find_entry(section, name); - if (ent == NULL) - ent = create_entry(section, name); - - sprintf(ent->data, "%04X", val); - mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata)); -} - - -void -config_set_hex20(char *head, char *name, int val) -{ - section_t *section; - entry_t *ent; - - section = find_section(head); - if (section == NULL) - section = create_section(head); - - ent = find_entry(section, name); - if (ent == NULL) - ent = create_entry(section, name); - - sprintf(ent->data, "%05X", val); - mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata)); -} - - -void -config_set_mac(char *head, char *name, int val) -{ - section_t *section; - entry_t *ent; - - section = find_section(head); - if (section == NULL) - section = create_section(head); - - ent = find_entry(section, name); - if (ent == NULL) - ent = create_entry(section, name); - - sprintf(ent->data, "%02x:%02x:%02x", - (val>>16)&0xff, (val>>8)&0xff, val&0xff); - mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata)); -} - - -void -config_set_string(char *head, char *name, char *val) -{ - section_t *section; - entry_t *ent; - - section = find_section(head); - if (section == NULL) - section = create_section(head); - - ent = find_entry(section, name); - if (ent == NULL) - ent = create_entry(section, name); - - strncpy(ent->data, val, sizeof(ent->data)); - mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata)); -} - - -void -config_set_wstring(char *head, char *name, wchar_t *val) -{ - section_t *section; - entry_t *ent; - - section = find_section(head); - if (section == NULL) - section = create_section(head); - - ent = find_entry(section, name); - if (ent == NULL) - ent = create_entry(section, name); - - memcpy(ent->wdata, val, sizeof_w(ent->wdata)); - wcstombs(ent->data, ent->wdata, sizeof(ent->data)); -} diff --git a/backup code/disk/hdc_esdi_mfm.c b/backup code/disk/hdc_esdi_mfm.c deleted file mode 100644 index 8f7d80dd5..000000000 --- a/backup code/disk/hdc_esdi_mfm.c +++ /dev/null @@ -1,856 +0,0 @@ -/* - * 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. - * - * Driver for the MFM controller (WD1007-vse1) for PC/AT. - * - * Version: @(#)hdc_mfm_at.c 1.0.13 2018/05/02 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../pic.h" -#include "../rom.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../plat.h" -#include "../ui.h" -#include "hdc.h" -#include "hdd.h" - - -#define HDC_TIME (TIMER_USEC*10LL) -#define BIOS_FILE L"roms/hdd/mfm_at/62-000279-061.bin" - -#define STAT_ERR 0x01 -#define STAT_INDEX 0x02 -#define STAT_CORRECTED_DATA 0x04 -#define STAT_DRQ 0x08 /* Data request */ -#define STAT_DSC 0x10 -#define STAT_SEEK_COMPLETE 0x20 -#define STAT_READY 0x40 -#define STAT_BUSY 0x80 - -#define ERR_DAM_NOT_FOUND 0x01 /* Data Address Mark not found */ -#define ERR_TR000 0x02 /* track 0 not found */ -#define ERR_ABRT 0x04 /* command aborted */ -#define ERR_ID_NOT_FOUND 0x10 /* ID not found */ -#define ERR_DATA_CRC 0x40 /* data CRC error */ -#define ERR_BAD_BLOCK 0x80 /* bad block detected */ - -#define CMD_NOP 0x00 -#define CMD_RESTORE 0x10 -#define CMD_READ 0x20 -#define CMD_WRITE 0x30 -#define CMD_VERIFY 0x40 -#define CMD_FORMAT 0x50 -#define CMD_SEEK 0x70 -#define CMD_DIAGNOSE 0x90 -#define CMD_SET_PARAMETERS 0x91 -#define CMD_READ_PARAMETERS 0xec - - -typedef struct { - int cfg_spt; - int cfg_hpc; - int current_cylinder; - int real_spt; - int real_hpc; - int real_tracks; - int present; - int hdd_num; -} drive_t; - -typedef struct { - uint8_t status; - uint8_t error; - int secount,sector,cylinder,head,cylprecomp; - uint8_t command; - uint8_t fdisk; - int pos; - - int drive_sel; - int reset; - uint16_t buffer[256]; - int irqstat; - - int64_t callback; - - drive_t drives[2]; - - rom_t bios_rom; -} mfm_t; - - -#ifdef ENABLE_MFM_AT_LOG -int mfm_at_do_log = ENABLE_MFM_AT_LOG; -#endif - - -static void -mfm_at_log(const char *fmt, ...) -{ -#ifdef ENABLE_MFM_AT_LOG - va_list ap; - - if (mfm_at_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static inline void -irq_raise(mfm_t *mfm) -{ - if (!(mfm->fdisk & 2)) - picint(1 << 14); - - mfm->irqstat = 1; -} - - -static inline void -irq_lower(mfm_t *mfm) -{ - if (mfm->irqstat) { - if (!(mfm->fdisk & 2)) - picintc(1 << 14); - - mfm->irqstat = 0; - } -} - - -/* Return the sector offset for the current register values. */ -static int -get_sector(mfm_t *mfm, off64_t *addr) -{ - drive_t *drive = &mfm->drives[mfm->drive_sel]; - int heads = drive->cfg_hpc; - int sectors = drive->cfg_spt; - int c, h, s; - - if (mfm->head > heads) { - mfm_at_log("mfm_get_sector: past end of configured heads\n"); - return(1); - } - - if (mfm->sector >= sectors+1) { - mfm_at_log("mfm_get_sector: past end of configured sectors\n"); - return(1); - } - - if (drive->cfg_spt==drive->real_spt && drive->cfg_hpc==drive->real_hpc) { - *addr = ((((off64_t) mfm->cylinder * heads) + mfm->head) * - sectors) + (mfm->sector - 1); - } else { - /* - * When performing translation, the firmware seems to leave 1 - * sector per track inaccessible (spare sector) - */ - - *addr = ((((off64_t) mfm->cylinder * heads) + mfm->head) * - sectors) + (mfm->sector - 1); - - s = *addr % (drive->real_spt - 1); - h = (*addr / (drive->real_spt - 1)) % drive->real_hpc; - c = (*addr / (drive->real_spt - 1)) / drive->real_hpc; - - *addr = ((((off64_t)c * drive->real_hpc) + h) * drive->real_spt) + s; - } - - return(0); -} - - -/* Move to the next sector using CHS addressing. */ -static void -next_sector(mfm_t *mfm) -{ - drive_t *drive = &mfm->drives[mfm->drive_sel]; - - mfm->sector++; - if (mfm->sector == (drive->cfg_spt + 1)) { - mfm->sector = 1; - if (++mfm->head == drive->cfg_hpc) { - mfm->head = 0; - mfm->cylinder++; - if (drive->current_cylinder < drive->real_tracks) - drive->current_cylinder++; - } - } -} - - -static void -mfm_writew(uint16_t port, uint16_t val, void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - - mfm->buffer[mfm->pos >> 1] = val; - mfm->pos += 2; - - if (mfm->pos >= 512) { - mfm->pos = 0; - mfm->status = STAT_BUSY; - timer_clock(); - /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ - mfm->callback = (3125LL * TIMER_USEC) / 8LL; - timer_update_outstanding(); - } -} - - -static void -mfm_write(uint16_t port, uint8_t val, void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - - mfm_at_log("WD1007 write(%04x, %02x)\n", port, val); - - switch (port) { - case 0x1f0: /* data */ - mfm_writew(port, val | (val << 8), priv); - return; - - case 0x1f1: /* write precompensation */ - mfm->cylprecomp = val; - return; - - case 0x1f2: /* sector count */ - mfm->secount = val; - return; - - case 0x1f3: /* sector */ - mfm->sector = val; - return; - - case 0x1f4: /* cylinder low */ - mfm->cylinder = (mfm->cylinder & 0xFF00) | val; - return; - - case 0x1f5: /* cylinder high */ - mfm->cylinder = (mfm->cylinder & 0xFF) | (val << 8); - return; - - case 0x1f6: /* drive/Head */ - mfm->head = val & 0xF; - mfm->drive_sel = (val & 0x10) ? 1 : 0; - if (mfm->drives[mfm->drive_sel].present) { - mfm->status = STAT_READY|STAT_DSC; - } else { - mfm->status = 0; - } - return; - - case 0x1f7: /* command register */ - irq_lower(mfm); - mfm->command = val; - mfm->error = 0; - - mfm_at_log("WD1007: command %02x\n", val & 0xf0); - - switch (val & 0xf0) { - case CMD_RESTORE: - mfm->command &= ~0x0f; /*mask off step rate*/ - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - case CMD_SEEK: - mfm->command &= ~0x0f; /*mask off step rate*/ - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - default: - switch (val) { - case CMD_NOP: - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - case CMD_READ: - case CMD_READ+1: - case CMD_READ+2: - case CMD_READ+3: - mfm->command &= ~0x03; - if (val & 0x02) - fatal("Read with ECC\n"); - - case 0xa0: - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - case CMD_WRITE: - case CMD_WRITE+1: - case CMD_WRITE+2: - case CMD_WRITE+3: - mfm->command &= ~0x03; - if (val & 0x02) - fatal("Write with ECC\n"); - mfm->status = STAT_DRQ | STAT_DSC; - mfm->pos = 0; - break; - - case CMD_VERIFY: - case CMD_VERIFY+1: - mfm->command &= ~0x01; - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - case CMD_FORMAT: - mfm->status = STAT_DRQ; - mfm->pos = 0; - break; - - case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 30LL*HDC_TIME; - timer_update_outstanding(); - break; - - case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - case 0xe0: /*???*/ - case CMD_READ_PARAMETERS: - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - - default: - mfm_at_log("WD1007: bad command %02X\n", val); - case 0xe8: /*???*/ - mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200LL*HDC_TIME; - timer_update_outstanding(); - break; - } - } - break; - - case 0x3f6: /* Device control */ - if ((mfm->fdisk & 0x04) && !(val & 0x04)) { - timer_clock(); - mfm->callback = 500LL*HDC_TIME; - timer_update_outstanding(); - mfm->reset = 1; - mfm->status = STAT_BUSY; - } - - if (val & 0x04) { - /*Drive held in reset*/ - timer_clock(); - mfm->callback = 0LL; - timer_update_outstanding(); - mfm->status = STAT_BUSY; - } - mfm->fdisk = val; - /* Lower IRQ on IRQ disable. */ - if ((val & 2) && !(mfm->fdisk & 0x02)) - picintc(1 << 14); - break; - } -} - - -static uint16_t -mfm_readw(uint16_t port, void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - uint16_t temp; - - temp = mfm->buffer[mfm->pos >> 1]; - mfm->pos += 2; - - if (mfm->pos >= 512) { - mfm->pos=0; - mfm->status = STAT_READY | STAT_DSC; - if (mfm->command == CMD_READ || mfm->command == 0xa0) { - mfm->secount = (mfm->secount - 1) & 0xff; - if (mfm->secount) { - next_sector(mfm); - mfm->status = STAT_BUSY; - timer_clock(); - /* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */ - mfm->callback = (3125LL * TIMER_USEC) / 8LL; - timer_update_outstanding(); - } else { - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); - } - } - } - - return(temp); -} - - -static uint8_t -mfm_read(uint16_t port, void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - uint8_t temp = 0xff; - - switch (port) { - case 0x1f0: /* data */ - temp = mfm_readw(port, mfm) & 0xff; - break; - - case 0x1f1: /* error */ - temp = mfm->error; - break; - - case 0x1f2: /* sector count */ - temp = mfm->secount; - break; - - case 0x1f3: /* sector */ - temp = mfm->sector; - break; - - case 0x1f4: /* cylinder low */ - temp = (uint8_t)(mfm->cylinder&0xff); - break; - - case 0x1f5: /* cylinder high */ - temp = (uint8_t)(mfm->cylinder>>8); - break; - - case 0x1f6: /* drive/Head */ - temp = (uint8_t)(0xa0|mfm->head|(mfm->drive_sel?0x10:0)); - break; - - case 0x1f7: /* status */ - irq_lower(mfm); - temp = mfm->status; - break; - } - - mfm_at_log("WD1007 read(%04x) = %02x\n", port, temp); - - return(temp); -} - - -static void -mfm_callback(void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - drive_t *drive = &mfm->drives[mfm->drive_sel]; - off64_t addr; - - mfm->callback = 0LL; - if (mfm->reset) { - mfm->status = STAT_READY|STAT_DSC; - mfm->error = 1; - mfm->secount = 1; - mfm->sector = 1; - mfm->head = 0; - mfm->cylinder = 0; - mfm->reset = 0; - - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); - - return; - } - - mfm_at_log("WD1007: command %02x\n", mfm->command); - - switch (mfm->command) { - case CMD_RESTORE: - if (! drive->present) { - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - } else { - drive->current_cylinder = 0; - mfm->status = STAT_READY|STAT_DSC; - } - irq_raise(mfm); - break; - - case CMD_SEEK: - if (! drive->present) { - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - } else { - mfm->status = STAT_READY|STAT_DSC; - } - irq_raise(mfm); - break; - - case CMD_READ: - if (! drive->present) { - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - irq_raise(mfm); - break; - } - - if (get_sector(mfm, &addr)) { - mfm->error = ERR_ID_NOT_FOUND; - mfm->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(mfm); - break; - } - - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *)mfm->buffer); - - mfm->pos = 0; - mfm->status = STAT_DRQ|STAT_READY|STAT_DSC; - irq_raise(mfm); - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - break; - - case CMD_WRITE: - if (! drive->present) { - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - irq_raise(mfm); - break; - } - - if (get_sector(mfm, &addr)) { - mfm->error = ERR_ID_NOT_FOUND; - mfm->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(mfm); - break; - } - - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *)mfm->buffer); - - irq_raise(mfm); - mfm->secount = (mfm->secount - 1) & 0xff; - if (mfm->secount) { - mfm->status = STAT_DRQ|STAT_READY|STAT_DSC; - mfm->pos = 0; - next_sector(mfm); - } else { - mfm->status = STAT_READY|STAT_DSC; - } - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - break; - - case CMD_VERIFY: - if (! drive->present) { - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - irq_raise(mfm); - break; - } - - if (get_sector(mfm, &addr)) { - mfm->error = ERR_ID_NOT_FOUND; - mfm->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(mfm); - break; - } - - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *)mfm->buffer); - - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - next_sector(mfm); - mfm->secount = (mfm->secount - 1) & 0xff; - if (mfm->secount) - mfm->callback = 6LL*HDC_TIME; - else { - mfm->pos = 0; - mfm->status = STAT_READY|STAT_DSC; - irq_raise(mfm); - } - break; - - case CMD_FORMAT: - if (! drive->present) { - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - irq_raise(mfm); - break; - } - - if (get_sector(mfm, &addr)) { - mfm->error = ERR_ID_NOT_FOUND; - mfm->status = STAT_READY|STAT_DSC|STAT_ERR; - irq_raise(mfm); - break; - } - - hdd_image_zero(drive->hdd_num, addr, mfm->secount); - - mfm->status = STAT_READY|STAT_DSC; - irq_raise(mfm); - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1); - break; - - case CMD_DIAGNOSE: - mfm->error = 1; /*no error detected*/ - mfm->status = STAT_READY|STAT_DSC; - irq_raise(mfm); - break; - - case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ - if (drive->present == 0) { - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - irq_raise(mfm); - break; - } - - drive->cfg_spt = mfm->secount; - drive->cfg_hpc = mfm->head+1; - - mfm_at_log("WD1007: parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc); - - if (! mfm->secount) - fatal("WD1007: secount=0\n"); - mfm->status = STAT_READY|STAT_DSC; - irq_raise(mfm); - break; - - case CMD_NOP: - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - irq_raise(mfm); - break; - - case 0xe0: - if (! drive->present) { - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - irq_raise(mfm); - break; - } - - switch (mfm->cylinder >> 8) { - case 0x31: - mfm->cylinder = drive->real_tracks; - break; - - case 0x33: - mfm->cylinder = drive->real_hpc; - break; - - case 0x35: - mfm->cylinder = 0x200; - break; - - case 0x36: - mfm->cylinder = drive->real_spt; - break; - - default: - mfm_at_log("WD1007: bad read config %02x\n", - mfm->cylinder >> 8); - } - mfm->status = STAT_READY|STAT_DSC; - irq_raise(mfm); - break; - - case 0xa0: - if (! drive->present) { - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - } else { - memset(mfm->buffer, 0x00, 512); - memset(&mfm->buffer[3], 0xff, 512-6); - mfm->pos = 0; - mfm->status = STAT_DRQ|STAT_READY|STAT_DSC; - } - irq_raise(mfm); - break; - - case CMD_READ_PARAMETERS: - if (! drive->present) { - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - irq_raise(mfm); - break; - } - - memset(mfm->buffer, 0x00, 512); - mfm->buffer[0] = 0x44; /* general configuration */ - mfm->buffer[1] = drive->real_tracks; /* number of non-removable cylinders */ - mfm->buffer[2] = 0; /* number of removable cylinders */ - mfm->buffer[3] = drive->real_hpc; /* number of heads */ - mfm->buffer[4] = 600; /* number of unformatted bytes/track */ - mfm->buffer[5] = mfm->buffer[4] * drive->real_spt; /* number of unformatted bytes/sector */ - mfm->buffer[6] = drive->real_spt; /* number of sectors */ - mfm->buffer[7] = 0; /*minimum bytes in inter-sector gap*/ - mfm->buffer[8] = 0; /* minimum bytes in postamble */ - mfm->buffer[9] = 0; /* number of words of vendor status */ - /* controller info */ - mfm->buffer[20] = 2; /* controller type */ - mfm->buffer[21] = 1; /* sector buffer size, in sectors */ - mfm->buffer[22] = 0; /* ecc bytes appended */ - mfm->buffer[27] = 'W' | ('D' << 8); - mfm->buffer[28] = '1' | ('0' << 8); - mfm->buffer[29] = '0' | ('7' << 8); - mfm->buffer[30] = 'V' | ('-' << 8); - mfm->buffer[31] = 'S' | ('E' << 8); - mfm->buffer[32] = '1'; - mfm->buffer[47] = 0; /* sectors per interrupt */ - mfm->buffer[48] = 0; /* can use double word read/write? */ - mfm->pos = 0; - mfm->status = STAT_DRQ|STAT_READY|STAT_DSC; - irq_raise(mfm); - break; - - default: - mfm_at_log("WD1007: callback on unknown command %02x\n", mfm->command); - /*FALLTHROUGH*/ - - case 0xe8: - mfm->status = STAT_READY|STAT_ERR|STAT_DSC; - mfm->error = ERR_ABRT; - irq_raise(mfm); - break; - } - - ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0); -} - - -static void -loadhd(mfm_t *mfm, int hdd_num, int d, const wchar_t *fn) -{ - drive_t *drive = &mfm->drives[hdd_num]; - - if (! hdd_image_load(d)) { - mfm_at_log("WD1007: drive %d not present!\n", d); - drive->present = 0; - return; - } - - drive->cfg_spt = drive->real_spt = hdd[d].spt; - drive->cfg_hpc = drive->real_hpc = hdd[d].hpc; - drive->real_tracks = hdd[d].tracks; - drive->hdd_num = d; - drive->present = 1; -} - - -static void * -wd1007vse1_init(const device_t *info) -{ - int c, d; - - mfm_t *mfm = malloc(sizeof(mfm_t)); - memset(mfm, 0x00, sizeof(mfm_t)); - - c = 0; - for (d=0; d= MFM_NUM) break; - } - } - - mfm->status = STAT_READY|STAT_DSC; - mfm->error = 1; - - rom_init(&mfm->bios_rom, - BIOS_FILE, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - io_sethandler(0x01f0, 1, - mfm_read, mfm_readw, NULL, - mfm_write, mfm_writew, NULL, mfm); - io_sethandler(0x01f1, 7, - mfm_read, NULL, NULL, - mfm_write, NULL, NULL, mfm); - io_sethandler(0x03f6, 1, NULL, NULL, NULL, - mfm_write, NULL, NULL, mfm); - - timer_add(mfm_callback, &mfm->callback, &mfm->callback, mfm); - - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); - - return(mfm); -} - - -static void -wd1007vse1_close(void *priv) -{ - mfm_t *mfm = (mfm_t *)priv; - drive_t *drive; - int d; - - for (d=0; d<2; d++) { - drive = &mfm->drives[d]; - - hdd_image_close(drive->hdd_num); - } - - free(mfm); - - ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); -} - - -static int -wd1007vse1_available(void) -{ - return(rom_present(BIOS_FILE)); -} - - -const device_t mfm_at_wd1007vse1_device = { - "Western Digital WD1007V-SE1 (MFM)", - DEVICE_ISA | DEVICE_AT, - 0, - wd1007vse1_init, wd1007vse1_close, NULL, - wd1007vse1_available, - NULL, NULL, - NULL -}; diff --git a/backup code/disk/hdc_ide - Cópia.c b/backup code/disk/hdc_ide - Cópia.c deleted file mode 100644 index a59fb2f06..000000000 --- a/backup code/disk/hdc_ide - Cópia.c +++ /dev/null @@ -1,3023 +0,0 @@ -/* - * 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 IDE emulation for hard disks and ATAPI - * CD-ROM devices. - * - * Version: @(#)hdc_ide.c 1.0.46 2018/05/02 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#define __USE_LARGEFILE64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../mem.h" -#include "../pic.h" -#include "../pci.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../scsi/scsi.h" -#include "../cdrom/cdrom.h" -#include "../plat.h" -#include "../ui.h" -#include "hdc.h" -#include "hdc_ide.h" -#include "hdd.h" -#include "zip.h" - - -/* Bits of 'atastat' */ -#define ERR_STAT 0x01 /* Error */ -#define IDX_STAT 0x02 /* Index */ -#define CORR_STAT 0x04 /* Corrected data */ -#define DRQ_STAT 0x08 /* Data request */ -#define DSC_STAT 0x10 /* Drive seek complete */ -#define SERVICE_STAT 0x10 /* ATAPI service */ -#define DWF_STAT 0x20 /* Drive write fault */ -#define DRDY_STAT 0x40 /* Ready */ -#define BSY_STAT 0x80 /* Busy */ - -/* Bits of 'error' */ -#define AMNF_ERR 0x01 /* Address mark not found */ -#define TK0NF_ERR 0x02 /* Track 0 not found */ -#define ABRT_ERR 0x04 /* Command aborted */ -#define MCR_ERR 0x08 /* Media change request */ -#define IDNF_ERR 0x10 /* Sector ID not found */ -#define MC_ERR 0x20 /* Media change */ -#define UNC_ERR 0x40 /* Uncorrectable data error */ -#define BBK_ERR 0x80 /* Bad block mark detected */ - -/* ATA Commands */ -#define WIN_NOP 0x00 -#define WIN_SRST 0x08 /* ATAPI Device Reset */ -#define WIN_RECAL 0x10 -#define WIN_READ 0x20 /* 28-Bit Read */ -#define WIN_READ_NORETRY 0x21 /* 28-Bit Read - no retry */ -#define WIN_WRITE 0x30 /* 28-Bit Write */ -#define WIN_WRITE_NORETRY 0x31 /* 28-Bit Write - no retry */ -#define WIN_VERIFY 0x40 /* 28-Bit Verify */ -#define WIN_VERIFY_ONCE 0x41 /* Added by OBattler - deprected older ATA command, according to the specification I found, it is identical to 0x40 */ -#define WIN_FORMAT 0x50 -#define WIN_SEEK 0x70 -#define WIN_DRIVE_DIAGNOSTICS 0x90 /* Execute Drive Diagnostics */ -#define WIN_SPECIFY 0x91 /* Initialize Drive Parameters */ -#define WIN_PACKETCMD 0xA0 /* Send a packet command. */ -#define WIN_PIDENTIFY 0xA1 /* Identify ATAPI device */ -#define WIN_READ_MULTIPLE 0xC4 -#define WIN_WRITE_MULTIPLE 0xC5 -#define WIN_SET_MULTIPLE_MODE 0xC6 -#define WIN_READ_DMA 0xC8 -#define WIN_READ_DMA_ALT 0xC9 -#define WIN_WRITE_DMA 0xCA -#define WIN_WRITE_DMA_ALT 0xCB -#define WIN_STANDBYNOW1 0xE0 -#define WIN_IDLENOW1 0xE1 -#define WIN_SETIDLE1 0xE3 -#define WIN_CHECKPOWERMODE1 0xE5 -#define WIN_SLEEP1 0xE6 -#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ -#define WIN_SET_FEATURES 0xEF -#define WIN_READ_NATIVE_MAX 0xF8 - -#define FEATURE_SET_TRANSFER_MODE 0x03 -#define FEATURE_ENABLE_IRQ_OVERLAPPED 0x5d -#define FEATURE_ENABLE_IRQ_SERVICE 0x5e -#define FEATURE_DISABLE_REVERT 0x66 -#define FEATURE_ENABLE_REVERT 0xcc -#define FEATURE_DISABLE_IRQ_OVERLAPPED 0xdd -#define FEATURE_DISABLE_IRQ_SERVICE 0xde - -#if 0 -/* In the future, there's going to be just the IDE_ATAPI type, - leaving it to the common ATAPI/SCSI device handler to know - what type the device is. */ -enum -{ - IDE_NONE = 0, - IDE_HDD, - IDE_ATAPI -}; -#else -enum -{ - IDE_NONE = 0, - IDE_HDD, - IDE_CDROM, - IDE_ZIP -}; -#endif - -#define IDE_PCI (PCI && (romset != ROM_PB640)) - - -typedef struct { - int bit32, cur_dev, - irq; - int64_t callback; -} ide_board_t; - -static ide_board_t *ide_boards[4]; - -ide_t *ide_drives[IDE_NUM]; -int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv); -int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv); -void (*ide_bus_master_set_irq)(int channel, void *priv); -void *ide_bus_master_priv[2]; -int ide_inited = 0; -int ide_ter_enabled = 0, ide_qua_enabled = 0; - -static uint16_t ide_base_main[4] = { 0x1f0, 0x170, 0x168, 0x1e8 }; -static uint16_t ide_side_main[4] = { 0x3f6, 0x376, 0x36e, 0x3ee }; - -static void ide_callback(void *priv); - - -#define IDE_TIME (20LL * TIMER_USEC) / 3LL - - -#ifdef ENABLE_IDE_LOG -int ide_do_log = ENABLE_IDE_LOG; -#endif - - -static void -ide_log(const char *fmt, ...) -{ -#ifdef ENABLE_IDE_LOG - va_list ap; - - if (ide_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -uint8_t -getstat(ide_t *ide) { - return ide->atastat; -} - - -int64_t -ide_get_period(ide_t *ide, int size) -{ - double period = 10.0 / 3.0; - - switch(ide->mdma_mode & 0x300) { - case 0x000: /* PIO */ - switch(ide->mdma_mode & 0xff) { - case 0: - period = 10.0 / 3.0; - break; - case 1: - period = (period * 600.0) / 383.0; - break; - case 2: - period = 25.0 / 3.0; - break; - case 3: - period = 100.0 / 9.0; - break; - case 4: - period = 50.0 / 3.0; - break; - } - break; - case 0x100: /* Single Word DMA */ - switch(ide->mdma_mode & 0xff) { - case 0: - period = 25.0 / 12.0; - break; - case 1: - period = 25.0 / 6.0; - break; - case 2: - period = 25.0 / 3.0; - break; - } - break; - case 0x200: /* Multiword DMA */ - switch(ide->mdma_mode & 0xff) { - case 0: - period = 25.0 / 6.0; - break; - case 1: - period = 40.0 / 3.0; - break; - case 2: - period = 50.0 / 3.0; - break; - } - break; - case 0x300: /* Ultra DMA */ - switch(ide->mdma_mode & 0xff) { - case 0: - period = 50.0 / 3.0; - break; - case 1: - period = 25.0; - break; - case 2: - period = 100.0 / 3.0; - break; - case 3: - period = 400.0 / 9.0; - break; - case 4: - period = 200.0 / 3.0; - break; - case 5: - period = 100.0; - break; - } - break; - } - - period *= 1048576.0; /* period * MB */ - period = 1000000.0 / period; - period *= (double) TIMER_USEC; - period *= (double) size; - return (int64_t) period; -} - - -#if 0 -int64_t -ide_get_seek_time(ide_t *ide, uint32_t new_pos) -{ - double dusec, time; - uint32_t pos = hdd_image_get_pos(ide->hdd_num); - uint32_t t, nt; - t = pos / ide->spt; - nt = new_pos / ide->spt; - - dusec = (double) TIMER_USEC; - time = (1000000.0 / 2800.0) * dusec; /* Revolution (1/2800 s). */ - - if ((t % ide->hpc) != (pos % ide->hpc)) /* Head change. */ - time += (dusec / 250.0); /* 4ns */ - - t /= ide->hpc; - nt /= ide->hpc; - - if (t != nt) { - t = ABS(t - nt); - time += ((40000.0 * dusec) / ((double) ide->tracks)) * ((double) t); - } - return (int64_t) time; -} -#endif - - -int -ide_drive_is_cdrom(ide_t *ide) -{ - int ch = ide->channel; - - if (ch >= 8) - return 0; - - if (atapi_cdrom_drives[ch] >= CDROM_NUM) - return 0; - else { - if (cdrom_drives[atapi_cdrom_drives[ch]].bus_type == CDROM_BUS_ATAPI) - return 1; - else - return 0; - } -} - - -int -ide_drive_is_zip(ide_t *ide) -{ - int ch = ide->channel; - - if (ch >= 8) - return 0; - - if (atapi_zip_drives[ch] >= ZIP_NUM) - return 0; - else { - if (zip_drives[atapi_zip_drives[ch]].bus_type == ZIP_BUS_ATAPI) - return 1; - else - return 0; - } -} - - -void -ide_irq_raise(ide_t *ide) -{ - if (!ide_boards[ide->board]) - return; - - /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ - - if (!(ide->fdisk & 2) && (ide_boards[ide->board]->irq != -1)) { - if ((ide->board < 2) && ide_bus_master_set_irq) - ide_bus_master_set_irq(ide->board | 0x40, ide_bus_master_priv[ide->board]); - else - picint(1 << ide_boards[ide->board]->irq); - } - - ide->irqstat=1; - ide->service=1; -} - - -void -ide_irq_lower(ide_t *ide) -{ - if (!ide_boards[ide->board]) - return; - - /* ide_log("Lowering IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ - - if ((ide_boards[ide->board]->irq != -1) && ide->irqstat) { - if ((ide->board < 2) && ide_bus_master_set_irq) - ide_bus_master_set_irq(ide->board, ide_bus_master_priv[ide->board]); - else - picintc(1 << ide_boards[ide->board]->irq); - } - - ide->irqstat=0; -} - - -/** - * Copy a string into a buffer, padding with spaces, and placing characters as - * if they were packed into 16-bit values, stored little-endian. - * - * @param str Destination buffer - * @param src Source string - * @param len Length of destination buffer to fill in. Strings shorter than - * this length will be padded with spaces. - */ -static void -ide_padstr(char *str, const char *src, int len) -{ - int i, v; - - for (i = 0; i < len; i++) { - if (*src != '\0') - v = *src++; - else - v = ' '; - str[i ^ 1] = v; - } -} - - -/** - * Copy a string into a buffer, padding with spaces. Does not add string - * terminator. - * - * @param buf Destination buffer - * @param buf_size Size of destination buffer to fill in. Strings shorter than - * this length will be padded with spaces. - * @param src Source string - */ -void ide_padstr8(uint8_t *buf, int buf_size, const char *src) -{ - int i; - - for (i = 0; i < buf_size; i++) { - if (*src != '\0') - buf[i] = *src++; - else - buf[i] = ' '; - } -} - - -/* Type: - 0 = PIO, - 1 = SDMA, - 2 = MDMA, - 3 = UDMA - Return: - -1 = Not supported, - Anything else = maximum mode - - This will eventually be hookable. */ -enum { - TYPE_PIO = 0, - TYPE_SDMA, - TYPE_MDMA, - TYPE_UDMA -}; - -static int -ide_get_max(ide_t *ide, int type) -{ - switch(type) { - case TYPE_PIO: /* PIO */ - if (!IDE_PCI || (ide->board >= 2)) - return 0; /* Maximum PIO 0 for legacy PIO-only drive. */ - else { - if (ide_drive_is_zip(ide)) - return 3; - else - return 4; - } - break; - case TYPE_SDMA: /* SDMA */ - if (!IDE_PCI || (ide->board >= 2) || ide_drive_is_zip(ide)) - return -1; - else - return 2; - case TYPE_MDMA: /* MDMA */ - if (!IDE_PCI || (ide->board >= 2)) - return -1; - else { - if (ide_drive_is_zip(ide)) - return 1; - else - return 2; - } - case TYPE_UDMA: /* UDMA */ - if (!IDE_PCI || (ide->board >= 2)) - return -1; - else - return 2; - default: - fatal("Unknown transfer type: %i\n", type); - return -1; - } -} - - -/* Return: - 0 = Not supported, - Anything else = timings - - This will eventually be hookable. */ -enum { - TIMINGS_DMA = 0, - TIMINGS_PIO, - TIMINGS_PIO_FC -}; - -static int -ide_get_timings(ide_t *ide, int type) -{ - switch(type) { - case TIMINGS_DMA: - if (!IDE_PCI || (ide->board >= 2)) - return 0; - else { - if (ide_drive_is_zip(ide)) - return 0x96; - else - return 120; - } - break; - case TIMINGS_PIO: - if (!IDE_PCI || (ide->board >= 2)) - return 0; - else { - if (ide_drive_is_zip(ide)) - return 0xb4; - else - return 120; - } - break; - case TIMINGS_PIO_FC: - if (!IDE_PCI || (ide->board >= 2)) - return 0; - else { - if (ide_drive_is_zip(ide)) - return 0xb4; - else - return 0; - } - break; - default: - fatal("Unknown transfer type: %i\n", type); - return 0; - } -} - - -/** - * Fill in ide->buffer with the output of the "IDENTIFY DEVICE" command - */ -static void ide_hd_identify(ide_t *ide) -{ - char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; - - uint32_t d_hpc, d_spt, d_tracks; - uint64_t full_size = (hdd[ide->hdd_num].tracks * hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); - - device_identify[6] = (ide->hdd_num / 10) + 0x30; - device_identify[7] = (ide->hdd_num % 10) + 0x30; - ide_log("IDE Identify: %s\n", device_identify); - - d_spt = ide->spt; - if (ide->hpc <= 16) { - /* HPC <= 16, report as needed. */ - d_tracks = ide->tracks; - d_hpc = ide->hpc; - } else { - /* HPC > 16, convert to 16 HPC. */ - d_hpc = 16; - d_tracks = (ide->tracks * ide->hpc) / 16; - } - - /* Specify default CHS translation */ - if (full_size <= 16514064) { - ide->buffer[1] = d_tracks; /* Tracks in default CHS translation. */ - ide->buffer[3] = d_hpc; /* Heads in default CHS translation. */ - ide->buffer[6] = d_spt; /* Heads in default CHS translation. */ - } else { - ide->buffer[1] = 16383; /* Tracks in default CHS translation. */ - ide->buffer[3] = 16; /* Heads in default CHS translation. */ - ide->buffer[6] = 63; /* Heads in default CHS translation. */ - } - ide_log("Default CHS translation: %i, %i, %i\n", ide->buffer[1], ide->buffer[3], ide->buffer[6]); - - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ - ide->buffer[20] = 3; /*Buffer type*/ - ide->buffer[21] = 512; /*Buffer size*/ - ide->buffer[50] = 0x4000; /* Capabilities */ - ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; - - if ((ide->tracks >= 1024) || (ide->hpc > 16) || (ide->spt > 63)) { - ide->buffer[49] = (1 << 9); - ide_log("LBA supported\n"); - - ide->buffer[60] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */ - ide->buffer[61] = (full_size >> 16) & 0x0FFF; - ide_log("Full size: %" PRIu64 "\n", full_size); - - /* - Bit 0 = The fields reported in words 54-58 are valid; - Bit 1 = The fields reported in words 64-70 are valid; - Bit 2 = The fields reported in word 88 are valid. */ - ide->buffer[53] = 1; - - if (ide->cfg_spt != 0) { - ide->buffer[54] = (full_size / ide->cfg_hpc) / ide->cfg_spt; - ide->buffer[55] = ide->cfg_hpc; - ide->buffer[56] = ide->cfg_spt; - } else { - if (full_size <= 16514064) { - ide->buffer[54] = d_tracks; - ide->buffer[55] = d_hpc; - ide->buffer[56] = d_spt; - } else { - ide->buffer[54] = 16383; - ide->buffer[55] = 16; - ide->buffer[56] = 63; - } - } - - full_size = ((uint64_t) ide->buffer[54]) * ((uint64_t) ide->buffer[55]) * ((uint64_t) ide->buffer[56]); - - ide->buffer[57] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */ - ide->buffer[58] = (full_size >> 16) & 0x0FFF; - - ide_log("Current CHS translation: %i, %i, %i\n", ide->buffer[54], ide->buffer[55], ide->buffer[56]); - } - - if (IDE_PCI && (ide->board < 2)) { - ide->buffer[47] = 32 | 0x8000; /*Max sectors on multiple transfer command*/ - ide->buffer[80] = 0x1e; /*ATA-1 to ATA-4 supported*/ - ide->buffer[81] = 0x18; /*ATA-4 revision 18 supported*/ - } else { - ide->buffer[47] = 16 | 0x8000; /*Max sectors on multiple transfer command*/ - ide->buffer[80] = 0x0e; /*ATA-1 to ATA-3 supported*/ - } -} - - -/** - * Fill in ide->buffer with the output of the "IDENTIFY PACKET DEVICE" command - */ -static void -ide_atapi_cdrom_identify(ide_t *ide) -{ - char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; - - uint8_t cdrom_id; - - cdrom_id = atapi_cdrom_drives[ide->channel]; - - device_identify[7] = cdrom_id + 0x30; - ide_log("ATAPI Identify: %s\n", device_identify); - - ide->buffer[0] = 0x8000 | (5<<8) | 0x80 | (2<<5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ -#if 0 - ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ -#else - ide_padstr((char *) (ide->buffer + 23), "4.20 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:273 ", 40); /* Model */ -#endif - ide->buffer[49] = 0x200; /* LBA supported */ - ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ - - if (IDE_PCI && (ide->board < 2)) { - ide->buffer[71] = 30; - ide->buffer[72] = 30; - } -} - - -static void -ide_atapi_zip_100_identify(ide_t *ide) -{ - ide_padstr((char *) (ide->buffer + 23), "E.08", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */ -} - - -static void -ide_atapi_zip_250_identify(ide_t *ide) -{ - ide_padstr((char *) (ide->buffer + 23), "42.S", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 250 ATAPI", 40); /* Model */ - - if (IDE_PCI && (ide->board < 2)) { - ide->buffer[80] = 0x30; /*Supported ATA versions : ATA/ATAPI-4 ATA/ATAPI-5*/ - ide->buffer[81] = 0x15; /*Maximum ATA revision supported : ATA/ATAPI-5 T13 1321D revision 1*/ - } -} - - -static void -ide_atapi_zip_identify(ide_t *ide) -{ - uint8_t zip_id; - - zip_id = atapi_zip_drives[ide->channel]; - - /* Using (2<<5) below makes the ASUS P/I-P54TP4XE misdentify the ZIP drive - as a LS-120. */ - ide->buffer[0] = 0x8000 | (0<<8) | 0x80 | (1<<5); /* ATAPI device, direct-access device, removable media, interrupt DRQ */ - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide->buffer[49] = 0x200; /* LBA supported */ - ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ - - if (zip_drives[zip_id].is_250) - ide_atapi_zip_250_identify(ide); - else - ide_atapi_zip_100_identify(ide); -} - -static void -ide_identify(ide_t *ide) -{ - int d, i, max_pio, max_sdma, max_mdma, max_udma; - - ide_log("IDE IDENTIFY or IDENTIFY PACKET DEVICE on board %i (channel %i)\n", ide->board, ide->channel); - - memset(ide->buffer, 0, 512); - - if (ide_drive_is_cdrom(ide)) - ide_atapi_cdrom_identify(ide); - else if (ide_drive_is_zip(ide)) - ide_atapi_zip_identify(ide); - else if (ide->type != IDE_NONE) - ide_hd_identify(ide); - else { - fatal("IDE IDENTIFY or IDENTIFY PACKET DEVICE on non-attached IDE device\n"); - return; - } - - max_pio = ide_get_max(ide, TYPE_PIO); - max_sdma = ide_get_max(ide, TYPE_SDMA); - max_mdma = ide_get_max(ide, TYPE_MDMA); - max_udma = ide_get_max(ide, TYPE_UDMA); - - if (ide_boards[ide->board]->bit32) - ide->buffer[48] |= 1; /*Dword transfers supported*/ - ide->buffer[51] = ide_get_timings(ide, TIMINGS_PIO); - ide->buffer[53] &= 0x0006; - ide->buffer[52] = ide->buffer[62] = ide->buffer[63] = ide->buffer[64] = 0x0000; - ide->buffer[65] = ide->buffer[66] = ide->buffer[67] = ide->buffer[68] = 0x0000; - ide->buffer[88] = 0x0000; - - if (max_pio >= 3) { - ide->buffer[53] |= 0x0002; - ide->buffer[67] = ide_get_timings(ide, TIMINGS_PIO); - ide->buffer[68] = ide_get_timings(ide, TIMINGS_PIO_FC); - for (i = 3; i <= max_pio; i++) - ide->buffer[64] |= (1 << (i - 3)); - } - if (max_sdma != -1) { - for (i = 0; i <= max_sdma; i++) - ide->buffer[62] |= (1 << i); - } - if (max_mdma != -1) { - for (i = 0; i <= max_mdma; i++) - ide->buffer[63] |= (1 << i); - } - if (max_udma != -1) { - ide->buffer[53] |= 0x0004; - for (i = 0; i <= max_udma; i++) - ide->buffer[88] |= (1 << i); - } - - if ((max_sdma != -1) || (max_mdma != -1) || (max_udma != -1)) { - ide->buffer[49] |= 0x100; /* DMA supported */ - ide->buffer[52] = ide_get_timings(ide, TIMINGS_DMA); - } - - if ((max_mdma != -1) || (max_udma != -1)) { - ide->buffer[65] = ide_get_timings(ide, TIMINGS_DMA); - ide->buffer[66] = ide_get_timings(ide, TIMINGS_DMA); - } - - if (ide->mdma_mode != -1) { - d = (ide->mdma_mode & 0xff); - d <<= 8; - if ((ide->mdma_mode & 0x300) == 0x000) { - if ((ide->mdma_mode & 0xff) >= 3) - ide->buffer[64] |= d; - } else if ((ide->mdma_mode & 0x300) == 0x100) - ide->buffer[62] |= d; - else if ((ide->mdma_mode & 0x300) == 0x200) - ide->buffer[63] |= d; - else if ((ide->mdma_mode & 0x300) == 0x300) - ide->buffer[88] |= d; - ide_log("PIDENTIFY DMA Mode: %04X, %04X\n", ide->buffer[62], ide->buffer[63]); - } -} - - -/* - * Return the sector offset for the current register values - */ -static off64_t -ide_get_sector(ide_t *ide) -{ - uint32_t heads, sectors; - - if (ide->lba) - return (off64_t)ide->lba_addr + ide->skip512; - else { - heads = ide->cfg_hpc; - sectors = ide->cfg_spt; - - return ((((off64_t) ide->cylinder * heads) + ide->head) * - sectors) + (ide->sector - 1) + ide->skip512; - } -} - - -/** - * Move to the next sector using CHS addressing - */ -static void -ide_next_sector(ide_t *ide) -{ - if (ide->lba) - ide->lba_addr++; - else { - ide->sector++; - if (ide->sector == (ide->cfg_spt + 1)) { - ide->sector = 1; - ide->head++; - if (ide->head == ide->cfg_hpc) { - ide->head = 0; - ide->cylinder++; - } - } - } -} - - -static void -loadhd(ide_t *ide, int d, const wchar_t *fn) -{ - if (! hdd_image_load(d)) { - ide->type = IDE_NONE; - return; - } - - ide->spt = hdd[d].spt; - ide->hpc = hdd[d].hpc; - ide->tracks = hdd[d].tracks; - ide->type = IDE_HDD; - ide->hdd_num = d; -} - - -void -ide_set_signature(ide_t *ide) -{ - uint8_t cdrom_id = atapi_cdrom_drives[ide->channel]; - uint8_t zip_id = atapi_zip_drives[ide->channel]; - - ide->sector=1; - ide->head=0; - - if (ide_drive_is_zip(ide)) { - zip_set_signature(zip_id); - ide->secount = zip[zip_id]->phase; - ide->cylinder = zip[zip_id]->request_length; - } else if (ide_drive_is_cdrom(ide)) { - cdrom_set_signature(cdrom[cdrom_id]); - ide->secount = cdrom[cdrom_id]->phase; - ide->cylinder = cdrom[cdrom_id]->request_length; - } else { - ide->secount=1; - ide->cylinder=((ide->type == IDE_HDD) ? 0 : 0xFFFF); - if (ide->type == IDE_HDD) - ide->drive = 0; - } -} - - -static int -ide_set_features(ide_t *ide) -{ - uint8_t features, features_data; - int mode, submode, max; - - features = ide->cylprecomp; - features_data = ide->secount; - - ide_log("Features code %02X\n", features); - - ide_log("IDE %02X: Set features: %02X, %02X\n", ide->channel, features, features_data); - - switch(features) { - case FEATURE_SET_TRANSFER_MODE: /* Set transfer mode. */ - ide_log("Transfer mode %02X\n", features_data >> 3); - - mode = (features_data >> 3); - submode = features_data & 7; - - switch(mode) { - case 0x00: /* PIO default */ - if (submode != 0) - return 0; - max = ide_get_max(ide, TYPE_PIO); - ide->mdma_mode = (1 << max); - ide_log("IDE %02X: Setting DPIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; - - case 0x01: /* PIO mode */ - max = ide_get_max(ide, TYPE_PIO); - if (submode > max) - return 0; - ide->mdma_mode = (1 << submode); - ide_log("IDE %02X: Setting PIO mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; - - case 0x02: /* Singleword DMA mode */ - max = ide_get_max(ide, TYPE_SDMA); - if (submode > max) - return 0; - ide->mdma_mode = (1 << submode) | 0x100; - ide_log("IDE %02X: Setting SDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; - - case 0x04: /* Multiword DMA mode */ - max = ide_get_max(ide, TYPE_MDMA); - if (submode > max) - return 0; - ide->mdma_mode = (1 << submode) | 0x200; - ide_log("IDE %02X: Setting MDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; - - case 0x08: /* Ultra DMA mode */ - max = ide_get_max(ide, TYPE_UDMA); - if (submode > max) - return 0; - ide->mdma_mode = (1 << submode) | 0x300; - ide_log("IDE %02X: Setting UDMA mode: %02X, %08X\n", ide->channel, submode, ide->mdma_mode); - break; - - default: - return 0; - } - - case FEATURE_ENABLE_IRQ_OVERLAPPED: - case FEATURE_ENABLE_IRQ_SERVICE: - case FEATURE_DISABLE_IRQ_OVERLAPPED: - case FEATURE_DISABLE_IRQ_SERVICE: - max = ide_get_max(ide, TYPE_MDMA); - if (max == -1) - return 0; - else - return 1; - - case FEATURE_DISABLE_REVERT: /* Disable reverting to power on defaults. */ - case FEATURE_ENABLE_REVERT: /* Enable reverting to power on defaults. */ - return 1; - - default: - return 0; - } - - return 1; -} - - -void -ide_set_sector(ide_t *ide, int64_t sector_num) -{ - unsigned int cyl, r; - if (ide->lba) { - ide->head = (sector_num >> 24); - ide->cylinder = (sector_num >> 8); - ide->sector = (sector_num); - } else { - cyl = sector_num / (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); - r = sector_num % (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); - ide->cylinder = cyl; - ide->head = ((r / hdd[ide->hdd_num].spt) & 0x0f); - ide->sector = (r % hdd[ide->hdd_num].spt) + 1; - } -} - - -static void -ide_zero(int d) -{ - ide_t *dev; - ide_drives[d] = (ide_t *) malloc(sizeof(ide_t)); - memset(ide_drives[d], 0, sizeof(ide_t)); - dev = ide_drives[d]; - dev->channel = d; - dev->type = IDE_NONE; - dev->hdd_num = -1; - dev->atastat = DRDY_STAT | DSC_STAT; - dev->service = 0; - dev->board = d >> 1; -} - - -static void -ide_board_close(int board) -{ - ide_t *dev; - int c, d; - - /* Close hard disk image files (if previously open) */ - for (d = 0; d < 2; d++) { - c = (board << 1) + d; - dev = ide_drives[c]; - - if ((dev->type == IDE_HDD) && (dev->hdd_num != -1)) - hdd_image_close(dev->hdd_num); - - if (board < 4) { - if (ide_drive_is_zip(dev)) - zip[atapi_zip_drives[c]]->status = DRDY_STAT | DSC_STAT; - else if (ide_drive_is_cdrom(dev)) - cdrom[atapi_cdrom_drives[c]]->status = DRDY_STAT | DSC_STAT; - } - - if (dev->buffer) - free(dev->buffer); - - if (dev->sector_buffer) - free(dev->sector_buffer); - - if (dev) - free(dev); - } -} - - -static void -ide_board_init(int board) -{ - ide_t *dev; - int c, d; - int max, ch; - int is_ide, valid_ch; - int min_ch, max_ch; - - min_ch = (board << 1); - max_ch = min_ch + 1; - - ide_log("IDE: board %i: loading disks...\n", board); - for (d = 0; d < 2; d++) { - c = (board << 1) + d; - ide_zero(c); - } - - c = 0; - for (d = 0; d < HDD_NUM; d++) { - is_ide = (hdd[d].bus == HDD_BUS_IDE); - ch = hdd[d].ide_channel; - - if (board == 4) { - valid_ch = ((ch >= 0) && (ch <= 1)); - ch |= 8; - } else - valid_ch = ((ch >= min_ch) && (ch <= max_ch)); - - if (is_ide && valid_ch) { - ide_log("Found IDE hard disk on channel %i\n", ch); - loadhd(ide_drives[ch], d, hdd[d].fn); - ide_drives[ch]->sector_buffer = (uint8_t *) malloc(256*512); - memset(ide_drives[ch]->sector_buffer, 0, 256*512); - if (++c >= 2) break; - } - } - ide_log("IDE: board %i: done, loaded %d disks.\n", board, c); - - for (d = 0; d < 2; d++) { - c = (board << 1) + d; - dev = ide_drives[c]; - - if (board < 4) { - if (ide_drive_is_zip(dev) && (dev->type == IDE_NONE)) - dev->type = IDE_ZIP; - else if (ide_drive_is_cdrom(dev) && (dev->type == IDE_NONE)) - dev->type = IDE_CDROM; - } - - if (dev->type != IDE_NONE) { - dev->buffer = (uint16_t *) malloc(65536 * sizeof(uint16_t)); - memset(dev->buffer, 0, 65536 * sizeof(uint16_t)); - } - - ide_set_signature(dev); - - max = ide_get_max(dev, TYPE_PIO); - dev->mdma_mode = (1 << max); - dev->error = 1; - dev->cfg_spt = dev->cfg_hpc = 0; - } -} - - -void -ide_set_callback(uint8_t board, int64_t callback) -{ - ide_board_t *dev = ide_boards[board]; - - ide_log("ide_set_callback(%i)\n", board); - - if (!dev) { - ide_log("Set callback failed\n"); - return; - } - - if (callback) - dev->callback = callback; - else - dev->callback = 0LL; -} - - -void -ide_write_data(ide_t *ide, uint32_t val, int length) -{ - int ch = ide->channel; - - uint8_t *idebufferb = (uint8_t *) ide->buffer; - uint16_t *idebufferw = ide->buffer; - uint32_t *idebufferl = (uint32_t *) ide->buffer; - - if (ide->command == WIN_PACKETCMD) { - ide->pos = 0; - - if (!ide_drive_is_zip(ide) && !ide_drive_is_cdrom(ide)) - return; - - if (ide_drive_is_zip(ide)) - zip_write(ch, val, length); - else - cdrom_write(ch, val, length); - return; - } else { - switch(length) { - case 1: - idebufferb[ide->pos] = val & 0xff; - ide->pos++; - break; - case 2: - idebufferw[ide->pos >> 1] = val & 0xffff; - ide->pos += 2; - break; - case 4: - idebufferl[ide->pos >> 2] = val; - ide->pos += 4; - break; - default: - return; - } - - if (ide->pos>=512) { - ide->pos=0; - ide->atastat = BSY_STAT; - timer_process(); - if (ide->command == WIN_WRITE_MULTIPLE) - ide_callback(ide_boards[ide->board]); - else - ide_set_callback(ide->board, ide_get_period(ide, 512)); - timer_update_outstanding(); - } - } -} - - -void -ide_writew(uint16_t addr, uint16_t val, void *priv) -{ - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - - /* ide_log("ide_writew %04X %04X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); */ - - addr &= 0x7; - - if ((ide->type == IDE_NONE) && ((addr == 0x0) || (addr == 0x7))) - return; - - switch (addr) { - case 0x0: /* Data */ - ide_write_data(ide, val, 2); - break; - } -} - - -static void -ide_writel(uint16_t addr, uint32_t val, void *priv) -{ - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - - /* ide_log("ide_writel %04X %08X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); */ - - addr &= 0x7; - - if ((ide->type == IDE_NONE) && ((addr == 0x0) || (addr == 0x7))) - return; - - switch (addr) { - case 0x0: /* Data */ - ide_write_data(ide, val & 0xffff, 2); - ide_write_data(ide, val >> 16, 2); - break; - } -} - - -void -ide_write_devctl(uint16_t addr, uint8_t val, void *priv) -{ - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide, *ide_other; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - ide_other = ide_drives[ch ^ 1]; - - ide_log("ide_write_devctl %04X %02X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); - - if ((ide->fdisk & 4) && !(val&4) && (ide->type != IDE_NONE || ide_other->type != IDE_NONE)) { - timer_process(); - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 0LL; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 0LL; - ide_set_callback(ide->board, 500LL * IDE_TIME); - timer_update_outstanding(); - - if (ide->type != IDE_NONE) - ide->reset = 1; - if (ide_other->type != IDE_NONE) - ide->reset = 1; - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - ide->atastat = ide_other->atastat = BSY_STAT; - } - - if (val & 4) { - /*Drive held in reset*/ - timer_process(); - ide_set_callback(ide->board, 0LL); - timer_update_outstanding(); - ide->atastat = ide_other->atastat = BSY_STAT; - } - ide->fdisk = ide_other->fdisk = val; - return; -} - - -void -ide_writeb(uint16_t addr, uint8_t val, void *priv) -{ - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide, *ide_other; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - ide_other = ide_drives[ch ^ 1]; - - ide_log("ide_write %04X %02X from %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); - - addr &= 0x7; - - if ((ide->type == IDE_NONE) && ((addr == 0x0) || (addr == 0x7))) - return; - - switch (addr) { - case 0x0: /* Data */ - ide_write_data(ide, val | (val << 8), 2); - return; - - /* Note to self: for ATAPI, bit 0 of this is DMA if set, PIO if clear. */ - case 0x1: /* Features */ - if (ide_drive_is_zip(ide)) { - ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO"); - zip[atapi_zip_drives[ch]]->features = val; - } else if (ide_drive_is_cdrom(ide)) { - ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO"); - cdrom[atapi_cdrom_drives[ch]]->features = val; - } - ide->cylprecomp = val; - - if (ide_drive_is_zip(ide_other)) - zip[atapi_zip_drives[ch ^ 1]]->features = val; - else if (ide_drive_is_cdrom(ide_other)) - cdrom[atapi_cdrom_drives[ch ^ 1]]->features = val; - ide_other->cylprecomp = val; - return; - - case 0x2: /* Sector count */ - if (ide_drive_is_zip(ide)) { - ide_log("Sector count write: %i\n", val); - zip[atapi_zip_drives[ch]]->phase = val; - } else if (ide_drive_is_cdrom(ide)) { - ide_log("Sector count write: %i\n", val); - cdrom[atapi_cdrom_drives[ch]]->phase = val; - } - ide->secount = val; - - if (ide_drive_is_zip(ide_other)) { - ide_log("Other sector count write: %i\n", val); - zip[atapi_zip_drives[ch ^ 1]]->phase = val; - } else if (ide_drive_is_cdrom(ide_other)) { - ide_log("Other sector count write: %i\n", val); - cdrom[atapi_cdrom_drives[ch ^ 1]]->phase = val; - } - ide_other->secount = val; - return; - - case 0x3: /* Sector */ - ide->sector = val; - ide->lba_addr = (ide->lba_addr & 0xFFFFF00) | val; - ide_other->sector = val; - ide_other->lba_addr = (ide_other->lba_addr & 0xFFFFF00) | val; - return; - - case 0x4: /* Cylinder low */ - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ch]]->request_length &= 0xFF00; - zip[atapi_zip_drives[ch]]->request_length |= val; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ch]]->request_length &= 0xFF00; - cdrom[atapi_cdrom_drives[ch]]->request_length |= val; - } - ide->cylinder = (ide->cylinder & 0xFF00) | val; - ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); - - if (ide_drive_is_zip(ide_other)) { - zip[atapi_zip_drives[ch ^ 1]]->request_length &= 0xFF00; - zip[atapi_zip_drives[ch ^ 1]]->request_length |= val; - } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[ch ^ 1]]->request_length &= 0xFF00; - cdrom[atapi_cdrom_drives[ch ^ 1]]->request_length |= val; - } - ide_other->cylinder = (ide_other->cylinder & 0xFF00) | val; - ide_other->lba_addr = (ide_other->lba_addr & 0xFFF00FF) | (val << 8); - return; - - case 0x5: /* Cylinder high */ - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ch]]->request_length &= 0xFF; - zip[atapi_zip_drives[ch]]->request_length |= (val << 8); - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ch]]->request_length &= 0xFF; - cdrom[atapi_cdrom_drives[ch]]->request_length |= (val << 8); - } - ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); - ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); - - if (ide_drive_is_zip(ide_other)) { - zip[atapi_zip_drives[ch ^ 1]]->request_length &= 0xFF; - zip[atapi_zip_drives[ch ^ 1]]->request_length |= (val << 8); - } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[ch ^ 1]]->request_length &= 0xFF; - cdrom[atapi_cdrom_drives[ch ^ 1]]->request_length |= (val << 8); - } - ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); - ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); - return; - - case 0x6: /* Drive/Head */ - if (ch != ((val >> 4) & 1) + (ide->board << 1)) { - ide_boards[ide->board]->cur_dev = ((val >> 4) & 1) + (ide->board << 1); - ch = ide_boards[ide->board]->cur_dev; - - if (ide->reset || ide_other->reset) { - ide->atastat = ide_other->atastat = DRDY_STAT | DSC_STAT; - ide->error = ide_other->error = 1; - ide->secount = ide_other->secount = 1; - ide->sector = ide_other->sector = 1; - ide->head = ide_other->head = 0; - ide->cylinder = ide_other->cylinder = 0; - ide->reset = ide_other->reset = 0; - - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ide->channel]]->status = DRDY_STAT | DSC_STAT; - zip[atapi_zip_drives[ide->channel]]->error = 1; - zip[atapi_zip_drives[ide->channel]]->phase = 1; - zip[atapi_zip_drives[ide->channel]]->request_length = 0xEB14; - zip[atapi_zip_drives[ide->channel]]->callback = 0LL; - ide->cylinder = 0xEB14; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]]->status = DRDY_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ide->channel]]->error = 1; - cdrom[atapi_cdrom_drives[ide->channel]]->phase = 1; - cdrom[atapi_cdrom_drives[ide->channel]]->request_length = 0xEB14; - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 0LL; - ide->cylinder = 0xEB14; - } - - if (ide_drive_is_zip(ide_other)) { - zip[atapi_zip_drives[ide_other->channel]]->status = DRDY_STAT | DSC_STAT; - zip[atapi_zip_drives[ide_other->channel]]->error = 1; - zip[atapi_zip_drives[ide_other->channel]]->phase = 1; - zip[atapi_zip_drives[ide_other->channel]]->request_length = 0xEB14; - zip[atapi_zip_drives[ide_other->channel]]->callback = 0LL; - ide->cylinder = 0xEB14; - } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[ide_other->channel]]->status = DRDY_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ide_other->channel]]->error = 1; - cdrom[atapi_cdrom_drives[ide_other->channel]]->phase = 1; - cdrom[atapi_cdrom_drives[ide_other->channel]]->request_length = 0xEB14; - cdrom[atapi_cdrom_drives[ide_other->channel]]->callback = 0LL; - ide->cylinder = 0xEB14; - } - - ide_set_callback(ide->board, 0LL); - timer_update_outstanding(); - return; - } - - ide = ide_drives[ch]; - } - - ide->head = val & 0xF; - ide->lba = val & 0x40; - ide_other->head = val & 0xF; - ide_other->lba = val & 0x40; - - ide->lba_addr = (ide->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24); - ide_other->lba_addr = (ide_other->lba_addr & 0x0FFFFFF)|((val & 0xF) << 24); - return; - - case 0x7: /* Command register */ - if (ide->type == IDE_NONE) - return; - - ide_irq_lower(ide); - ide->command=val; - - ide->error=0; - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->error = 0; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->error = 0; - - if (((val >= WIN_RECAL) && (val <= 0x1F)) || ((val >= WIN_SEEK) && (val <= 0x7F))) { - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = DRDY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = DRDY_STAT; - else - ide->atastat = BSY_STAT; - timer_process(); - - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 100LL*IDE_TIME; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 100LL*IDE_TIME; - ide_set_callback(ide->board, 100LL * IDE_TIME); - timer_update_outstanding(); - return; - } - - switch (val) { - case WIN_SRST: /* ATAPI Device Reset */ - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - else - ide->atastat = DRDY_STAT; - timer_process(); - - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 100LL*IDE_TIME; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 100LL*IDE_TIME; - ide_set_callback(ide->board, 100LL * IDE_TIME); - timer_update_outstanding(); - return; - - case WIN_READ_MULTIPLE: - /* Fatal removed in accordance with the official ATAPI reference: - If the Read Multiple command is attempted before the Set Multiple Mode - command has been executed or when Read Multiple commands are - disabled, the Read Multiple operation is rejected with an Aborted Com- - mand error. */ - ide->blockcount = 0; - /* Turn on the activity indicator *here* so that it gets turned on - less times. */ - /* ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); */ - - case WIN_READ: - case WIN_READ_NORETRY: - case WIN_READ_DMA: - case WIN_READ_DMA_ALT: - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - else - ide->atastat = BSY_STAT; - timer_process(); - - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 200LL*IDE_TIME; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME; - if (ide->type == IDE_HDD) { - if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) { - if (ide->secount) - ide_set_callback(ide->board, ide_get_period(ide, (int) ide->secount << 9)); - else - ide_set_callback(ide->board, ide_get_period(ide, 131072)); - } else - ide_set_callback(ide->board, ide_get_period(ide, 512)); - } else - ide_set_callback(ide->board, 200LL * IDE_TIME); - timer_update_outstanding(); - ide->do_initial_read = 1; - return; - - case WIN_WRITE_MULTIPLE: - if (!ide->blocksize && !ide_drive_is_zip(ide) && !ide_drive_is_cdrom(ide)) - fatal("Write_MULTIPLE - blocksize = 0\n"); - ide->blockcount = 0; - /* Turn on the activity indicator *here* so that it gets turned on - less times. */ - /* ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); */ - - case WIN_WRITE: - case WIN_WRITE_NORETRY: - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ide->channel]]->status = DRQ_STAT | DSC_STAT | DRDY_STAT; - zip[atapi_zip_drives[ide->channel]]->pos = 0; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]]->status = DRQ_STAT | DSC_STAT | DRDY_STAT; - cdrom[atapi_cdrom_drives[ide->channel]]->pos = 0; - } else { - ide->atastat = DRQ_STAT | DSC_STAT | DRDY_STAT; - ide->pos=0; - } - return; - - case WIN_WRITE_DMA: - case WIN_WRITE_DMA_ALT: - case WIN_VERIFY: - case WIN_VERIFY_ONCE: - case WIN_IDENTIFY: /* Identify Device */ - case WIN_SET_FEATURES: /* Set Features */ - case WIN_READ_NATIVE_MAX: - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - else - ide->atastat = BSY_STAT; - timer_process(); - - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 200LL*IDE_TIME; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME; - if ((ide->type == IDE_HDD) && - ((val == WIN_WRITE_DMA) || (val == WIN_WRITE_DMA_ALT))) { - if (ide->secount) - ide_set_callback(ide->board, ide_get_period(ide, (int) ide->secount << 9)); - else - ide_set_callback(ide->board, ide_get_period(ide, 131072)); - } else if ((ide->type == IDE_HDD) && - ((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) - ide_set_callback(ide->board, ide_get_period(ide, 512)); - else - ide_set_callback(ide->board, 200LL * IDE_TIME); - timer_update_outstanding(); - return; - - case WIN_FORMAT: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto ide_bad_command; - else { - ide->atastat = DRQ_STAT; - ide->pos=0; - } - return; - - case WIN_SPECIFY: /* Initialize Drive Parameters */ - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - else - ide->atastat = BSY_STAT; - timer_process(); - - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 30LL*IDE_TIME; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 30LL*IDE_TIME; - ide_set_callback(ide->board, 30LL * IDE_TIME); - timer_update_outstanding(); - return; - - case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - else - ide->atastat = BSY_STAT; - - if (ide_drive_is_zip(ide_other)) - zip[atapi_zip_drives[ide_other->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide_other)) - cdrom[atapi_cdrom_drives[ide_other->channel]]->status = BSY_STAT; - else - ide_other->atastat = BSY_STAT; - - timer_process(); - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->callback = 200LL * IDE_TIME; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL * IDE_TIME; - ide_set_callback(ide->board, 200LL * IDE_TIME); - timer_update_outstanding(); - return; - - case WIN_PIDENTIFY: /* Identify Packet Device */ - case WIN_SET_MULTIPLE_MODE: /* Set Multiple Mode */ - case WIN_NOP: - case WIN_STANDBYNOW1: - case WIN_IDLENOW1: - case WIN_SETIDLE1: /* Idle */ - case WIN_CHECKPOWERMODE1: - case WIN_SLEEP1: - if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]]->status = BSY_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]]->status = BSY_STAT; - else - ide->atastat = BSY_STAT; - timer_process(); - ide_callback(dev); - timer_update_outstanding(); - return; - - case WIN_PACKETCMD: /* ATAPI Packet */ - /* Skip the command callback wait, and process immediately. */ - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ide->channel]]->packet_status = ZIP_PHASE_IDLE; - zip[atapi_zip_drives[ide->channel]]->pos=0; - zip[atapi_zip_drives[ide->channel]]->phase = 1; - zip[atapi_zip_drives[ide->channel]]->status = DRDY_STAT | DRQ_STAT; - ide_irq_raise(ide); /* Interrupt DRQ, requires IRQ on any DRQ. */ - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]]->packet_status = CDROM_PHASE_IDLE; - cdrom[atapi_cdrom_drives[ide->channel]]->pos=0; - cdrom[atapi_cdrom_drives[ide->channel]]->phase = 1; - cdrom[atapi_cdrom_drives[ide->channel]]->status = DRDY_STAT | DRQ_STAT; - } else { - ide->atastat = BSY_STAT; - timer_process(); - ide_set_callback(ide->board, 200LL * IDE_TIME); - timer_update_outstanding(); - ide->pos=0; - } - return; - - case 0xF0: - default: -ide_bad_command: - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ide->channel]]->status = DRDY_STAT | ERR_STAT | DSC_STAT; - zip[atapi_zip_drives[ide->channel]]->error = ABRT_ERR; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]]->status = DRDY_STAT | ERR_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ide->channel]]->error = ABRT_ERR; - } else { - ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - } - ide_irq_raise(ide); - return; - } - return; - } -} - - -static uint32_t -ide_read_data(ide_t *ide, int length) -{ - int ch = ide->channel; - uint32_t temp; - - if (!ide->buffer) { - switch (length) { - case 1: - return 0xff; - case 2: - return 0xffff; - case 4: - return 0xffffffff; - default: - return 0; - } - } - - uint8_t *idebufferb = (uint8_t *) ide->buffer; - uint16_t *idebufferw = ide->buffer; - uint32_t *idebufferl = (uint32_t *) ide->buffer; - - if (ide->command == WIN_PACKETCMD) { - ide->pos = 0; - if (!ide_drive_is_zip(ide) && !ide_drive_is_cdrom(ide)) { - ide_log("Drive not ZIP or CD-ROM (position: %i)\n", ide->pos); - return 0; - } - if (ide_drive_is_zip(ide)) - temp = zip_read(ch, length); - else - temp = cdrom_read(ch, length); - } else { - switch (length) { - case 1: - temp = idebufferb[ide->pos]; - ide->pos++; - break; - case 2: - temp = idebufferw[ide->pos >> 1]; - ide->pos += 2; - break; - case 4: - temp = idebufferl[ide->pos >> 2]; - ide->pos += 4; - break; - default: - return 0; - } - } - if (ide->pos>=512 && ide->command != WIN_PACKETCMD) { - ide->pos=0; - ide->atastat = DRDY_STAT | DSC_STAT; - if (ide_drive_is_zip(ide)) { - zip[atapi_zip_drives[ch]]->status = DRDY_STAT | DSC_STAT; - zip[atapi_zip_drives[ch]]->packet_status = ZIP_PHASE_IDLE; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ch]]->status = DRDY_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ch]]->packet_status = CDROM_PHASE_IDLE; - } - if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY || ide->command == WIN_READ_MULTIPLE) { - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide_next_sector(ide); - ide->atastat = BSY_STAT; - timer_process(); - if (ide->command == WIN_READ_MULTIPLE) - ide_callback(ide_boards[ide->board]); - else - ide_set_callback(ide->board, ide_get_period(ide, 512)); - timer_update_outstanding(); - } else { - if (ide->command != WIN_READ_MULTIPLE) - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } - } - } - - return temp; -} - - -static uint8_t -ide_status(ide_t *ide, int ch) -{ - if (ide->type == IDE_NONE) - return 0; - else { - if (ide_drive_is_zip(ide)) - return (zip[atapi_zip_drives[ch]]->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); - else if (ide_drive_is_cdrom(ide)) - return (cdrom[atapi_cdrom_drives[ch]]->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); - else - return ide->atastat; - } -} - - -uint8_t -ide_readb(uint16_t addr, void *priv) -{ - ide_board_t *dev = (ide_board_t *) priv; - - int ch; - ide_t *ide; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - - uint8_t temp = 0xff; - uint16_t tempw; - - addr |= 0x90; - addr &= 0xFFF7; - - switch (addr & 0x7) { - case 0x0: /* Data */ - tempw = ide_read_data(ide, 2); - temp = tempw & 0xff; - break; - - /* For ATAPI: Bits 7-4 = sense key, bit 3 = MCR (media change requested), - Bit 2 = ABRT (aborted command), Bit 1 = EOM (end of media), - and Bit 0 = ILI (illegal length indication). */ - case 0x1: /* Error */ - if (ide->type == IDE_NONE) - temp = 0; - else { - if (ide_drive_is_zip(ide)) - temp = zip[atapi_zip_drives[ch]]->error; - else if (ide_drive_is_cdrom(ide)) - temp = cdrom[atapi_cdrom_drives[ch]]->error; - else - temp = ide->error; - } - break; - - /* For ATAPI: - Bit 0: Command or Data: - Data if clear, Command if set; - Bit 1: I/OB - Direction: - To device if set; - From device if clear. - IO DRQ CoD - 0 1 1 Ready to accept command packet - 1 1 1 Message - ready to send message to host - 1 1 0 Data to host - 0 1 0 Data from host - 1 0 1 Status. */ - case 0x2: /* Sector count */ - if (ide_drive_is_zip(ide)) - temp = zip[atapi_zip_drives[ch]]->phase; - else if (ide_drive_is_cdrom(ide)) - temp = cdrom[atapi_cdrom_drives[ch]]->phase; - else - temp = ide->secount; - break; - - case 0x3: /* Sector */ - temp = (uint8_t)ide->sector; - break; - - case 0x4: /* Cylinder low */ - if (ide->type == IDE_NONE) - temp = 0xFF; - else { - if (ide_drive_is_zip(ide)) - temp = zip[atapi_zip_drives[ch]]->request_length & 0xff; - else if (ide_drive_is_cdrom(ide)) - temp = cdrom[atapi_cdrom_drives[ch]]->request_length & 0xff; - else - temp = ide->cylinder & 0xff; - } - break; - - case 0x5: /* Cylinder high */ - if (ide->type == IDE_NONE) - temp = 0xFF; - else { - if (ide_drive_is_zip(ide)) - temp = zip[atapi_zip_drives[ch]]->request_length >> 8; - else if (ide_drive_is_cdrom(ide)) - temp = cdrom[atapi_cdrom_drives[ch]]->request_length >> 8; - else - temp = ide->cylinder >> 8; - } - break; - - case 0x6: /* Drive/Head */ - temp = (uint8_t)(ide->head | ((ch & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0); - break; - - /* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is - DF (drive fault). */ - case 0x7: /* Status */ - ide_irq_lower(ide); - temp = ide_status(ide, ch); - break; - } - - ide_log("ide_readb(%04X, %08X) = %02X\n", addr, priv, temp); - return temp; -} - - -uint8_t -ide_read_alt_status(uint16_t addr, void *priv) -{ - uint8_t temp = 0xff; - - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - - /* Per the Seagate ATA-3 specification: - Reading the alternate status does *NOT* clear the IRQ. */ - temp = ide_status(ide, ch); - - ide_log("ide_read_alt_status(%04X, %08X) = %02X\n", addr, priv, temp); - return temp; -} - - -uint16_t -ide_readw(uint16_t addr, void *priv) -{ - uint16_t temp = 0xffff; - - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - - switch (addr & 0x7) { - case 0x0: /* Data */ - temp = ide_read_data(ide, 2); - break; - } - - /* ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, temp); */ - return temp; -} - - -static uint32_t -ide_readl(uint16_t addr, void *priv) -{ - uint16_t temp2; - uint32_t temp = 0xffffffff; - - ide_board_t *dev = (ide_board_t *) priv; - - ide_t *ide; - int ch; - - ch = dev->cur_dev; - ide = ide_drives[ch]; - - switch (addr & 0x7) { - case 0x0: /* Data */ - temp2 = ide_read_data(ide, 2); - temp = temp2 | (ide_read_data(ide, 2) << 16); - break; - } - - /* ide_log("ide_readl(%04X, %08X) = %04X\n", addr, priv, temp); */ - return temp; -} - - -static void -ide_callback(void *priv) -{ - ide_t *ide, *ide_other; - int snum, ret, ch; - int cdrom_id, cdrom_id_other; - int zip_id, zip_id_other; - - ide_board_t *dev = (ide_board_t *) priv; - ch = dev->cur_dev; - - ide = ide_drives[ch]; - ide_other = ide_drives[ch ^ 1]; - - ide_set_callback(ide->board, 0LL); - - if (ide->reset) { - ide_log("CALLBACK RESET %i %i\n", ide->reset,ch); - - ide->atastat = ide_other->atastat = DRDY_STAT | DSC_STAT; - ide->error = ide_other->error = 1; - ide->secount = ide_other->secount = 1; - ide->sector = ide_other->sector = 1; - ide->head = ide_other->head = 0; - ide->cylinder = ide_other->cylinder = 0; - - // ide->cfg_spt = ide->cfg_hpc = 0; /* need new parameters (drive 0) */ - // ide_other->cfg_spt = ide_other->cfg_hpc = 0; /* need new parameters (drive 1) */ - - ide->reset = ide_other->reset = 0; - - ide_set_signature(ide); - if (ide_drive_is_zip(ide)) { - zip_id = atapi_zip_drives[ch]; - zip[zip_id]->status = DRDY_STAT | DSC_STAT; - zip[zip_id]->error = 1; - } else if (ide_drive_is_cdrom(ide)) { - cdrom_id = atapi_cdrom_drives[ch]; - cdrom[cdrom_id]->status = DRDY_STAT | DSC_STAT; - cdrom[cdrom_id]->error = 1; - if (cdrom[cdrom_id]->handler->stop) - cdrom[cdrom_id]->handler->stop(cdrom_id); - } - - ide_set_signature(ide_other); - if (ide_drive_is_zip(ide_other)) { - zip_id_other = atapi_zip_drives[ch ^ 1]; - zip[zip_id_other]->status = DRDY_STAT | DSC_STAT; - zip[zip_id_other]->error = 1; - } else if (ide_drive_is_cdrom(ide_other)) { - cdrom_id_other = atapi_cdrom_drives[ch ^ 1]; - cdrom[cdrom_id_other]->status = DRDY_STAT | DSC_STAT; - cdrom[cdrom_id_other]->error = 1; - if (cdrom[cdrom_id_other]->handler->stop) - cdrom[cdrom_id_other]->handler->stop(cdrom_id_other); - } - - return; - } - - ide_log("CALLBACK %02X %i %i\n", ide->command, ide->reset,ch); - - cdrom_id = atapi_cdrom_drives[ch]; - cdrom_id_other = atapi_cdrom_drives[ch ^ 1]; - - zip_id = atapi_zip_drives[ch]; - zip_id_other = atapi_zip_drives[ch ^ 1]; - - if (((ide->command >= WIN_RECAL) && (ide->command <= 0x1F)) || - ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F))) { - if (ide->type != IDE_HDD) - goto abort_cmd; - if ((ide->command >= WIN_SEEK) && (ide->command <= 0x7F)) { - if ((ide->cylinder >= ide->tracks) || (ide->head >= ide->hpc) || - !ide->sector || (ide->sector > ide->spt)) - goto id_not_found; - } - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - } - - switch (ide->command) { - /* Initialize the Task File Registers as follows: Status = 00h, Error = 01h, Sector Count = 01h, Sector Number = 01h, - Cylinder Low = 14h, Cylinder High =EBh and Drive/Head = 00h. */ - case WIN_SRST: /*ATAPI Device Reset */ - - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; /*Device passed*/ - ide->secount = 1; - ide->sector = 1; - - ide_set_signature(ide); - - if (ide_drive_is_zip(ide)) { - zip[zip_id]->status = DRDY_STAT | DSC_STAT; - zip[zip_id]->error = 1; - zip_reset(zip_id); - } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id]->status = DRDY_STAT | DSC_STAT; - cdrom[cdrom_id]->error = 1; - cdrom_reset(cdrom[cdrom_id]); - } - ide_irq_raise(ide); - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - ide->service = 0; - return; - - case WIN_NOP: - case WIN_STANDBYNOW1: - case WIN_IDLENOW1: - case WIN_SETIDLE1: - if (ide_drive_is_zip(ide)) - zip[zip_id]->status = DRDY_STAT | DSC_STAT; - else if (ide_drive_is_cdrom(ide)) - cdrom[cdrom_id]->status = DRDY_STAT | DSC_STAT; - else - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - - case WIN_CHECKPOWERMODE1: - case WIN_SLEEP1: - if (ide_drive_is_zip(ide)) { - zip[zip_id]->phase = 0xFF; - zip[zip_id]->status = DRDY_STAT | DSC_STAT; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id]->phase = 0xFF; - cdrom[cdrom_id]->status = DRDY_STAT | DSC_STAT; - } - ide->secount = 0xFF; - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - - case WIN_READ: - case WIN_READ_NORETRY: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) { - ide_set_signature(ide); - goto abort_cmd; - } - if (ide->cfg_spt == 0) - goto id_not_found; - - if (ide->do_initial_read) { - ide->do_initial_read = 0; - ide->sector_pos = 0; - if (ide->secount) - hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); - else - hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer); - } - - memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512); - - ide->sector_pos++; - ide->pos = 0; - - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - - ide_irq_raise(ide); - - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - return; - - case WIN_READ_DMA: - case WIN_READ_DMA_ALT: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide) || (ide->board >= 2)) { - ide_log("IDE %i: DMA read aborted (bad device or board)\n", ide->channel); - goto abort_cmd; - } - if (ide->cfg_spt == 0) { - ide_log("IDE %i: DMA read aborted (SPECIFY failed)\n", ide->channel); - goto id_not_found; - } - - ide->sector_pos = 0; - if (ide->secount) - ide->sector_pos = ide->secount; - else - ide->sector_pos = 256; - hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer); - - ide->pos=0; - - if (ide_bus_master_read) { - /* We should not abort - we should simply wait for the host to start DMA. */ - ret = ide_bus_master_read(ide->board, - ide->sector_buffer, ide->sector_pos * 512, - ide_bus_master_priv[ide->board]); - if (ret == 2) { - /* Bus master DMA disabled, simply wait for the host to enable DMA. */ - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_set_callback(ide->board, 6LL * IDE_TIME); - return; - } else if (ret == 1) { - /* Bus master DMAS error, abort the command. */ - ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); - goto abort_cmd; - } else { - /*DMA successful*/ - ide_log("IDE %i: DMA read successful\n", ide->channel); - - ide->atastat = DRDY_STAT | DSC_STAT; - - ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } - } else { - ide_log("IDE %i: DMA read aborted (no bus master)\n", ide->channel); - goto abort_cmd; - } - return; - - case WIN_READ_MULTIPLE: - /* According to the official ATA reference: - - If the Read Multiple command is attempted before the Set Multiple Mode - command has been executed or when Read Multiple commands are - disabled, the Read Multiple operation is rejected with an Aborted Com- - mand error. */ - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide) || !ide->blocksize) - goto abort_cmd; - if (ide->cfg_spt == 0) - goto id_not_found; - - if (ide->do_initial_read) { - ide->do_initial_read = 0; - ide->sector_pos = 0; - if (ide->secount) - hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); - else - hdd_image_read(ide->hdd_num, ide_get_sector(ide), 256, ide->sector_buffer); - } - - memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512); - - ide->sector_pos++; - ide->pos=0; - - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - if (!ide->blockcount) - ide_irq_raise(ide); - ide->blockcount++; - if (ide->blockcount >= ide->blocksize) - ide->blockcount = 0; - return; - - case WIN_WRITE: - case WIN_WRITE_NORETRY: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto abort_cmd; - if (ide->cfg_spt == 0) - goto id_not_found; - hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); - ide_irq_raise(ide); - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide->pos=0; - ide_next_sector(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } - return; - - case WIN_WRITE_DMA: - case WIN_WRITE_DMA_ALT: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide) || (ide->board >= 2)) { - ide_log("IDE %i: DMA write aborted (bad device type or board)\n", ide->channel); - goto abort_cmd; - } - if (ide->cfg_spt == 0) { - ide_log("IDE %i: DMA write aborted (SPECIFY failed)\n", ide->channel); - goto id_not_found; - } - - if (ide_bus_master_read) { - if (ide->secount) - ide->sector_pos = ide->secount; - else - ide->sector_pos = 256; - - ret = ide_bus_master_write(ide->board, - ide->sector_buffer, ide->sector_pos * 512, - ide_bus_master_priv[ide->board]); - - if (ret == 2) { - /* Bus master DMA disabled, simply wait for the host to enable DMA. */ - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_set_callback(ide->board, 6LL * IDE_TIME); - return; - } else if (ret == 1) { - /* Bus master DMA error, abort the command. */ - ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); - goto abort_cmd; - } else { - /*DMA successful*/ - ide_log("IDE %i: DMA write successful\n", ide->channel); - - hdd_image_write(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer); - - ide->atastat = DRDY_STAT | DSC_STAT; - - ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } - } else { - ide_log("IDE %i: DMA write aborted (no bus master)\n", ide->channel); - goto abort_cmd; - } - - return; - - case WIN_WRITE_MULTIPLE: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto abort_cmd; - if (ide->cfg_spt == 0) - goto id_not_found; - hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); - ide->blockcount++; - if (ide->blockcount >= ide->blocksize || ide->secount == 1) { - ide->blockcount = 0; - ide_irq_raise(ide); - } - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide->pos=0; - ide_next_sector(ide); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } - return; - - case WIN_VERIFY: - case WIN_VERIFY_ONCE: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto abort_cmd; - if (ide->cfg_spt == 0) - goto id_not_found; - ide->pos=0; - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); - return; - - case WIN_FORMAT: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto abort_cmd; - if (ide->cfg_spt == 0) - goto id_not_found; - hdd_image_zero(ide->hdd_num, ide_get_sector(ide), ide->secount); - - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - - /* ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); */ - return; - - case WIN_DRIVE_DIAGNOSTICS: - ide_set_signature(ide); - ide->error=1; /*No error detected*/ - - if (ide_drive_is_zip(ide)) { - zip[zip_id]->status = 0; - zip[zip_id]->error = 1; - ide_irq_raise(ide); - } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id]->status = 0; - cdrom[cdrom_id]->error = 1; - ide_irq_raise(ide); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; - ide_irq_raise(ide); - } - - ide_set_signature(ide_other); - ide_other->error=1; /*No error detected*/ - - if (ide_drive_is_zip(ide_other)) { - zip[zip_id_other]->status = 0; - zip[zip_id_other]->error = 1; - } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[cdrom_id_other]->status = 0; - cdrom[cdrom_id_other]->error = 1; - } else { - ide_other->atastat = DRDY_STAT | DSC_STAT; - ide_other->error = 1; - } - - ide_boards[ide->board]->cur_dev &= ~1; - ch = ide_boards[ide->board]->cur_dev; - return; - - case WIN_SPECIFY: /* Initialize Drive Parameters */ - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto abort_cmd; - if (ide->cfg_spt == 0) { - /* Only accept after RESET or DIAG. */ - ide->cfg_spt = ide->secount; - ide->cfg_hpc = ide->head + 1; - } - ide->command = 0x00; - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; - ide_irq_raise(ide); - return; - - case WIN_PIDENTIFY: /* Identify Packet Device */ - if (ide_drive_is_zip(ide)) { - ide_identify(ide); - ide->pos = 0; - zip[zip_id]->phase = 2; - zip[zip_id]->pos = 0; - zip[zip_id]->error = 0; - zip[zip_id]->status = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - } else if (ide_drive_is_cdrom(ide)) { - ide_identify(ide); - ide->pos = 0; - cdrom[cdrom_id]->phase = 2; - cdrom[cdrom_id]->pos = 0; - cdrom[cdrom_id]->error = 0; - cdrom[cdrom_id]->status = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - } - goto abort_cmd; - - case WIN_SET_MULTIPLE_MODE: - if (ide_drive_is_zip(ide) || ide_drive_is_cdrom(ide)) - goto abort_cmd; - ide->blocksize = ide->secount; - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - - case WIN_SET_FEATURES: - if (ide->type == IDE_NONE) - goto abort_cmd; - - if (!ide_set_features(ide)) - goto abort_cmd; - else { - if (ide_drive_is_zip(ide)) { - zip[zip_id]->status = DRDY_STAT | DSC_STAT; - zip[zip_id]->pos = 0; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id]->status = DRDY_STAT | DSC_STAT; - cdrom[cdrom_id]->pos = 0; - } - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - } - return; - - case WIN_READ_NATIVE_MAX: - if (ide->type != IDE_HDD) - goto abort_cmd; - snum = hdd[ide->hdd_num].spt; - snum *= hdd[ide->hdd_num].hpc; - snum *= hdd[ide->hdd_num].tracks; - ide_set_sector(ide, snum - 1); - ide->atastat = DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - - case WIN_IDENTIFY: /* Identify Device */ - if (ide->type != IDE_HDD) { - ide_set_signature(ide); - goto abort_cmd; - } else { - ide_identify(ide); - ide->pos=0; - ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; - ide_irq_raise(ide); - } - return; - - case WIN_PACKETCMD: /* ATAPI Packet */ - if (!ide_drive_is_zip(ide) && !ide_drive_is_cdrom(ide)) - goto abort_cmd; - - if (ide_drive_is_zip(ide)) - zip_phase_callback(atapi_zip_drives[ch]); - else - cdrom_phase_callback(cdrom[atapi_cdrom_drives[ch]]); - return; - - case 0xFF: - goto abort_cmd; - } - -abort_cmd: - ide->command = 0; - if (ide_drive_is_zip(ide)) { - zip[zip_id]->status = DRDY_STAT | ERR_STAT | DSC_STAT; - zip[zip_id]->error = ABRT_ERR; - zip[zip_id]->pos = 0; - } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id]->status = DRDY_STAT | ERR_STAT | DSC_STAT; - cdrom[cdrom_id]->error = ABRT_ERR; - cdrom[cdrom_id]->pos = 0; - } else { - ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - ide->pos = 0; - } - ide_irq_raise(ide); - return; - -id_not_found: - ide->atastat = DRDY_STAT | ERR_STAT | DSC_STAT; - ide->error = IDNF_ERR; - ide->pos = 0; - ide_irq_raise(ide); -} - - -static void -ide_set_handlers(uint8_t board) -{ - if (ide_base_main[board] & 0x300) { - if (ide_boards[board]->bit32) { - io_sethandler(ide_base_main[board], 1, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[board]); - } else { - io_sethandler(ide_base_main[board], 1, - ide_readb, ide_readw, NULL, - ide_writeb, ide_writew, NULL, - ide_boards[board]); - } - io_sethandler(ide_base_main[board] + 1, 7, - ide_readb, NULL, NULL, - ide_writeb, NULL, NULL, - ide_boards[board]); - } - if (ide_side_main[board] & 0x300) { - io_sethandler(ide_side_main[board], 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[board]); - } -} - - -static void -ide_remove_handlers(uint8_t board) -{ - if (ide_boards[board]->bit32) { - io_removehandler(ide_base_main[board], 1, - ide_readb, ide_readw, ide_readl, - ide_writeb, ide_writew, ide_writel, - ide_boards[board]); - } else { - io_removehandler(ide_base_main[board], 1, - ide_readb, ide_readw, NULL, - ide_writeb, ide_writew, NULL, - ide_boards[board]); - } - io_removehandler(ide_base_main[board] + 1, 7, - ide_readb, NULL, NULL, - ide_writeb, NULL, NULL, - ide_boards[board]); - io_removehandler(ide_side_main[board], 1, - ide_read_alt_status, NULL, NULL, - ide_write_devctl, NULL, NULL, - ide_boards[board]); -} - - -void -ide_pri_enable(void) -{ - ide_set_handlers(0); -} - - -void -ide_pri_disable(void) -{ - ide_remove_handlers(0); -} - - -void -ide_sec_enable(void) -{ - ide_set_handlers(1); -} - - -void -ide_sec_disable(void) -{ - ide_remove_handlers(1); -} - - -void -ide_set_base(int controller, uint16_t port) -{ - ide_base_main[controller] = port; -} - - -void -ide_set_side(int controller, uint16_t port) -{ - ide_side_main[controller] = port; -} - - -static void * -ide_ter_init(const device_t *info) -{ - ide_boards[2] = (ide_board_t *) malloc(sizeof(ide_board_t)); - memset(ide_boards[2], 0, sizeof(ide_board_t)); - - ide_boards[2]->irq = device_get_config_int("irq"); - ide_boards[2]->cur_dev = 4; - - ide_set_handlers(2); - - timer_add(ide_callback, &ide_boards[2]->callback, &ide_boards[2]->callback, ide_boards[2]); - - ide_board_init(2); - - return(ide_drives); -} - - -/* Close a standalone IDE unit. */ -static void -ide_ter_close(void *priv) -{ - if (ide_boards[2]) { - free(ide_boards[2]); - ide_boards[2] = NULL; - - ide_board_close(2); - } -} - - -static void * -ide_qua_init(const device_t *info) -{ - ide_boards[3] = (ide_board_t *) malloc(sizeof(ide_board_t)); - memset(ide_boards[3], 0, sizeof(ide_board_t)); - - ide_boards[3]->irq = device_get_config_int("irq"); - ide_boards[3]->cur_dev = 6; - - ide_set_handlers(3); - - timer_add(ide_callback, &ide_boards[3]->callback, &ide_boards[3]->callback, ide_boards[3]); - - ide_board_init(3); - - return(ide_drives); -} - - -/* Close a standalone IDE unit. */ -static void -ide_qua_close(void *priv) -{ - if (ide_boards[3]) { - free(ide_boards[3]); - ide_boards[3] = NULL; - - ide_board_close(3); - } -} - - -static void -ide_clear_bus_master(void) -{ - ide_bus_master_read = ide_bus_master_write = NULL; - ide_bus_master_set_irq = NULL; - ide_bus_master_priv[0] = ide_bus_master_priv[1] = NULL; -} - - -void * -ide_xtide_init(void) -{ - ide_clear_bus_master(); - - if (!ide_boards[0]) { - ide_boards[0] = (ide_board_t *) malloc(sizeof(ide_board_t)); - memset(ide_boards[0], 0, sizeof(ide_board_t)); - ide_boards[0]->cur_dev = 0; - - timer_add(ide_callback, &ide_boards[0]->callback, &ide_boards[0]->callback, - ide_boards[0]); - - ide_board_init(0); - } - ide_boards[0]->irq = -1; - - return ide_boards[0]; -} - - -void -ide_xtide_close(void) -{ - if (ide_boards[0]) { - free(ide_boards[0]); - ide_boards[0] = NULL; - - ide_board_close(0); - } -} - - -void -ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length, void *priv), - int (*write)(int channel, uint8_t *data, int transfer_length, void *priv), - void (*set_irq)(int channel, void *priv), - void *priv0, void *priv1) -{ - ide_bus_master_read = read; - ide_bus_master_write = write; - ide_bus_master_set_irq = set_irq; - ide_bus_master_priv[0] = priv0; - ide_bus_master_priv[1] = priv1; -} - - -void -secondary_ide_check(void) -{ - int i = 0; - int secondary_cdroms = 0; - int secondary_zips = 0; - - for (i=0; i= 2) && (zip_drives[i].ide_channel <= 3) && - (zip_drives[i].bus_type == ZIP_BUS_ATAPI)) - secondary_zips++; - } - for (i=0; i= 2) && (cdrom_drives[i].ide_channel <= 3) && - (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI)) - secondary_cdroms++; - } - if (!secondary_zips && !secondary_cdroms) - ide_remove_handlers(1); -} - - -/* - * Initialization of standalone IDE controller instance. - * - * Eventually, we should clean up the whole mess by only - * using const device_t units, with configuration parameters to - * indicate primary/secondary and all that, rather than - * keeping a zillion of duplicate functions around. - */ -static void * -ide_sainit(const device_t *info) -{ - ide_log("Initializing IDE...\n"); - - switch(info->local) { - case 0: /* ISA, single-channel */ - case 2: /* ISA, dual-channel */ - case 3: /* ISA, dual-channel, optional 2nd channel */ - case 4: /* VLB, single-channel */ - case 6: /* VLB, dual-channel */ - case 8: /* PCI, single-channel */ - case 10: /* PCI, dual-channel */ - if (!ide_inited) { - if (!(info->local & 8)) - ide_clear_bus_master(); - } - - if (!(ide_inited & 1)) { - ide_boards[0] = (ide_board_t *) malloc(sizeof(ide_board_t)); - memset(ide_boards[0], 0, sizeof(ide_board_t)); - ide_boards[0]->irq = 14; - ide_boards[0]->cur_dev = 0; - if (info->local & 8) - ide_boards[0]->bit32 = 1; - ide_base_main[0] = 0x1f0; - ide_side_main[0] = 0x3f6; - ide_set_handlers(0); - timer_add(ide_callback, &ide_boards[0]->callback, &ide_boards[0]->callback, - ide_boards[0]); - ide_log("Callback 0 pointer: %08X\n", &ide_boards[0]->callback); - - ide_board_init(0); - - ide_inited |= 1; - } - - if ((info->local & 3) && !(ide_inited & 2)) { - ide_boards[1] = (ide_board_t *) malloc(sizeof(ide_board_t)); - memset(ide_boards[1], 0, sizeof(ide_board_t)); - ide_boards[1]->irq = 15; - ide_boards[1]->cur_dev = 2; - if (info->local & 8) - ide_boards[1]->bit32 = 1; - ide_base_main[1] = 0x170; - ide_side_main[1] = 0x376; - ide_set_handlers(1); - timer_add(ide_callback, &ide_boards[1]->callback, &ide_boards[1]->callback, - ide_boards[1]); - ide_log("Callback 1 pointer: %08X\n", &ide_boards[1]->callback); - - ide_board_init(1); - - if (info->local & 1) - secondary_ide_check(); - - ide_inited |= 2; - } - break; - } - - return(ide_drives); -} - - -static void -ide_drive_reset(int d) -{ - ide_drives[d]->channel = d; - ide_drives[d]->atastat = DRDY_STAT | DSC_STAT; - ide_drives[d]->service = 0; - ide_drives[d]->board = d >> 1; - - if (ide_boards[d >> 1]) { - ide_boards[d >> 1]->cur_dev = d & ~1; - ide_boards[d >> 1]->callback = 0LL; - } - - ide_set_signature(ide_drives[d]); - - if (ide_drives[d]->sector_buffer) - memset(ide_drives[d]->sector_buffer, 0, 256*512); - - if (ide_drives[d]->buffer) - memset(ide_drives[d]->buffer, 0, 65536 * sizeof(uint16_t)); -} - - -/* Reset a standalone IDE unit. */ -static void -ide_sareset(void *p) -{ - int d; - - ide_log("Resetting IDE...\n"); - - if (ide_inited & 1) { - for (d = 0; d < 2; d++) - ide_drive_reset(d); - } - - if (ide_inited & 2) { - for (d = 2; d < 4; d++) - ide_drive_reset(d); - } -} - - -/* Close a standalone IDE unit. */ -static void -ide_saclose(void *priv) -{ - ide_log("Closing IDE...\n"); - - if ((ide_inited & 1) && (ide_boards[0])) { - free(ide_boards[0]); - ide_boards[0] = NULL; - - ide_board_close(0); - } - - if ((ide_inited & 2) && (ide_boards[1])) { - free(ide_boards[1]); - ide_boards[1] = NULL; - - ide_board_close(1); - } - - ide_inited = 0; -} - - -const device_t ide_isa_device = { - "ISA PC/AT IDE Controller", - DEVICE_ISA | DEVICE_AT, - 0, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -const device_t ide_isa_2ch_device = { - "ISA PC/AT IDE Controller (Dual-Channel)", - DEVICE_ISA | DEVICE_AT, - 2, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -const device_t ide_isa_2ch_opt_device = { - "ISA PC/AT IDE Controller (Single/Dual)", - DEVICE_ISA | DEVICE_AT, - 3, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -const device_t ide_vlb_device = { - "VLB IDE Controller", - DEVICE_VLB | DEVICE_AT, - 4, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -const device_t ide_vlb_2ch_device = { - "VLB IDE Controller (Dual-Channel)", - DEVICE_VLB | DEVICE_AT, - 6, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -const device_t ide_pci_device = { - "PCI IDE Controller", - DEVICE_PCI | DEVICE_AT, - 8, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -const device_t ide_pci_2ch_device = { - "PCI IDE Controller (Dual-Channel)", - DEVICE_PCI | DEVICE_AT, - 10, - ide_sainit, ide_saclose, ide_sareset, - NULL, NULL, NULL, NULL -}; - -static const device_config_t ide_ter_config[] = -{ - { - "irq", "IRQ", CONFIG_SELECTION, "", 10, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -static const device_config_t ide_qua_config[] = -{ - { - "irq", "IRQ", CONFIG_SELECTION, "", 11, - { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -const device_t ide_ter_device = { - "Tertiary IDE Controller", - DEVICE_AT, - 0, - ide_ter_init, ide_ter_close, NULL, - NULL, NULL, NULL, - ide_ter_config -}; - -const device_t ide_qua_device = { - "Quaternary IDE Controller", - DEVICE_AT, - 0, - ide_qua_init, ide_qua_close, NULL, - NULL, NULL, NULL, - ide_qua_config -}; diff --git a/backup code/disk/zip - Cópia.c b/backup code/disk/zip - Cópia.c deleted file mode 100644 index f95520eb3..000000000 --- a/backup code/disk/zip - Cópia.c +++ /dev/null @@ -1,2859 +0,0 @@ -/* - * 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 Iomega ZIP drive with SCSI(-like) - * commands, for both ATAPI and SCSI usage. - * - * Version: @(#)zip.c 1.0.21 2018/05/28 - * - * Author: Miran Grca, - * - * Copyright 2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" -#include "../timer.h" -#include "../device.h" -#include "../piix.h" -#include "../scsi/scsi.h" -#include "../nvr.h" -#include "../plat.h" -#include "../ui.h" -#include "hdc.h" -#include "hdc_ide.h" -#include "zip.h" - - -/* Bits of 'status' */ -#define ERR_STAT 0x01 -#define DRQ_STAT 0x08 /* Data request */ -#define DSC_STAT 0x10 -#define SERVICE_STAT 0x10 -#define READY_STAT 0x40 -#define BUSY_STAT 0x80 - -/* Bits of 'error' */ -#define ABRT_ERR 0x04 /* Command aborted */ -#define MCR_ERR 0x08 /* Media change request */ - -#define zipbufferb dev->buffer - - -zip_t *zip[ZIP_NUM]; -zip_drive_t zip_drives[ZIP_NUM]; -uint8_t atapi_zip_drives[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -uint8_t scsi_zip_drives[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }; - - -/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ -const uint8_t zip_command_flags[0x100] = -{ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ - 0, - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ - 0, - IMPLEMENTED, /* 0x06 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x08 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ - IMPLEMENTED, /* 0x0C */ - IMPLEMENTED | ATAPI_ONLY, /* 0x0D */ - 0, 0, 0, 0, - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ - 0, - IMPLEMENTED, /* 0x15 */ - IMPLEMENTED | SCSI_ONLY, /* 0x16 */ - IMPLEMENTED | SCSI_ONLY, /* 0x17 */ - 0, 0, - IMPLEMENTED, /* 0x1A */ - IMPLEMENTED | CHECK_READY, /* 0x1B */ - 0, - IMPLEMENTED, /* 0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, 0, - IMPLEMENTED | ATAPI_ONLY, /* 0x23 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x25 */ - 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x28 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ - 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, - IMPLEMENTED | CHECK_READY, /* 0x41 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0x55 */ - 0, 0, 0, 0, - IMPLEMENTED, /* 0x5A */ - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xA8 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0xAA */ - 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0xBD */ - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static uint64_t zip_mode_sense_page_flags = (1LL << GPMODE_R_W_ERROR_PAGE) | - (1LL << 0x02LL) | (1LL << 0x2FLL) | - (1LL << GPMODE_ALL_PAGES); -static uint64_t zip_250_mode_sense_page_flags = (1LL << GPMODE_R_W_ERROR_PAGE) | - (1LL << 0x05LL) | (1LL << 0x08LL) | - (1LL << 0x2FLL) | - (1LL << GPMODE_ALL_PAGES); - - -static const mode_sense_pages_t zip_mode_sense_pages_default = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 22, 0, 0, 0, 0, 90, 0, 0x50, 0x20 }, - { 0x02, 0x0e, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x2f, 0x04, 0x5c, 0x0f, 0xff, 0x0f } -} }; - -static const mode_sense_pages_t zip_250_mode_sense_pages_default = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x05, 0x1e, 0x80, 0, 0x40, 0x20, 2, 0, 0, 0xef, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0b, 0x7d, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x08, 0x0a, 4, 0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x2f, 0x04, 0x5c, 0x0f, 0x3c, 0x0f } -} }; - -static const mode_sense_pages_t zip_mode_sense_pages_default_scsi = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 22, 0, 0, 0, 0, 90, 0, 0x50, 0x20 }, - { 0x02, 0x0e, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x2f, 0x04, 0x5c, 0x0f, 0xff, 0x0f } -} }; - -static const mode_sense_pages_t zip_250_mode_sense_pages_default_scsi = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x05, 0x1e, 0x80, 0, 0x40, 0x20, 2, 0, 0, 0xef, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0b, 0x7d, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x08, 0x0a, 4, 0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x2f, 0x04, 0x5c, 0x0f, 0x3c, 0x0f } -} }; - -static const mode_sense_pages_t zip_mode_sense_pages_changeable = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 22, 0, 0, 0, 0, 90, 0, 0x50, 0x20 }, - { 0x02, 0x0e, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x2f, 0x04, 0x5c, 0x0f, 0xff, 0x0f } -} }; - -static const mode_sense_pages_t zip_250_mode_sense_pages_changeable = -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x05, 0x1e, 0x80, 0, 0x40, 0x20, 2, 0, 0, 0xef, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0b, 0x7d, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x08, 0x0a, 4, 0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0x2f, 0x04, 0x5c, 0x0f, 0x3c, 0x0f } -} }; - -static mode_sense_pages_t zip_mode_sense_pages_saved[ZIP_NUM]; - - -static void zip_command_complete(uint8_t id); - -void zip_init(int id, int cdb_len_setting); -void zip_phase_callback(uint8_t id); - - -#ifdef ENABLE_ZIP_LOG -int zip_do_log = ENABLE_ZIP_LOG; -#endif - - -static void -zip_log(const char *format, ...) -{ -#ifdef ENABLE_ZIP_LOG - va_list ap; - - if (zip_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -int -find_zip_for_channel(uint8_t channel) -{ - uint8_t i = 0; - - for (i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel == channel)) - return i; - } - return 0xff; -} - - -void -zip_destroy_drives(void) -{ - int i; - - for (i = 0; i < ZIP_NUM; i++) { - if (zip[i]) { - free(zip[i]); - zip[i] = NULL; - } - } -} - - -int -zip_load(uint8_t id, wchar_t *fn) -{ - int read_only = zip_drives[id].ui_writeprot; - int size = 0; - - zip_drives[id].f = plat_fopen(fn, zip_drives[id].ui_writeprot ? L"rb" : L"rb+"); - if (!zip_drives[id].ui_writeprot && !zip_drives[id].f) { - zip_drives[id].f = plat_fopen(fn, L"rb"); - read_only = 1; - } - if (zip_drives[id].f) { - fseek(zip_drives[id].f, 0, SEEK_END); - size = ftell(zip_drives[id].f); - - if ((size == ((ZIP_250_SECTORS << 9) + 0x1000)) || (size == ((ZIP_SECTORS << 9) + 0x1000))) { - /* This is a ZDI image. */ - size -= 0x1000; - zip_drives[id].base = 0x1000; - } else - zip_drives[id].base = 0; - - if (zip_drives[id].is_250) { - if ((size != (ZIP_250_SECTORS << 9)) && (size != (ZIP_SECTORS << 9))) { - zip_log("File is incorrect size for a ZIP image\nMust be exactly %i or %i bytes\n", - ZIP_250_SECTORS << 9, ZIP_SECTORS << 9); - fclose(zip_drives[id].f); - zip_drives[id].f = NULL; - zip_drives[id].medium_size = 0; - zip_eject(id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ - return 0; - } - } else { - if (size != (ZIP_SECTORS << 9)) { - zip_log("File is incorrect size for a ZIP image\nMust be exactly %i bytes\n", - ZIP_SECTORS << 9); - fclose(zip_drives[id].f); - zip_drives[id].f = NULL; - zip_drives[id].medium_size = 0; - zip_eject(id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ - return 0; - } - } - - zip_drives[id].medium_size = size >> 9; - - fseek(zip_drives[id].f, zip_drives[id].base, SEEK_SET); - - memcpy(zip_drives[id].image_path, fn, sizeof(zip_drives[id].image_path)); - - zip_drives[id].read_only = read_only; - - return 1; - } - - return 0; -} - - -void -zip_disk_reload(uint8_t id) -{ - zip_t *dev = zip[id]; - int ret = 0; - - if (wcslen(zip_drives[id].prev_image_path) == 0) - return; - else - ret = zip_load(id, zip_drives[id].prev_image_path); - - if (ret) - dev->unit_attention = 1; -} - - -void -zip_close(uint8_t id) -{ - if (zip_drives[id].f) { - fclose(zip_drives[id].f); - zip_drives[id].f = NULL; - - memcpy(zip_drives[id].prev_image_path, zip_drives[id].image_path, sizeof(zip_drives[id].prev_image_path)); - memset(zip_drives[id].image_path, 0, sizeof(zip_drives[id].image_path)); - - zip_drives[id].medium_size = 0; - } -} - - -void -build_atapi_zip_map() -{ - uint8_t i = 0; - - memset(atapi_zip_drives, 0xff, 8); - - for (i = 0; i < 8; i++) { - atapi_zip_drives[i] = find_zip_for_channel(i); - if (atapi_zip_drives[i] != 0xff) - zip_init(atapi_zip_drives[i], 12); - } -} - - -int -find_zip_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t i = 0; - - for (i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && (zip_drives[i].scsi_device_id == scsi_id) && (zip_drives[i].scsi_device_lun == scsi_lun)) - return i; - } - return 0xff; -} - - -void -build_scsi_zip_map() -{ - uint8_t i = 0; - uint8_t j = 0; - - for (i = 0; i < 16; i++) - memset(scsi_zip_drives[i], 0xff, 8); - - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) { - scsi_zip_drives[i][j] = find_zip_for_scsi_id(i, j); - if (scsi_zip_drives[i][j] != 0xff) - zip_init(scsi_zip_drives[i][j], 12); - } - } -} - - -static void -zip_set_callback(uint8_t id) -{ - zip_t *dev = zip[id]; - - if (zip_drives[id].bus_type != ZIP_BUS_SCSI) - ide_set_callback(zip_drives[id].ide_channel >> 1, dev->callback); -} - - -static void -zip_reset_cdb_len(int id) -{ - zip_t *dev = zip[id]; - - dev->cdb_len = dev->cdb_len_setting ? 16 : 12; -} - - -void -zip_set_signature(int id) -{ - zip_t *dev = zip[id]; - - if (id >= ZIP_NUM) - return; - dev->phase = 1; - dev->request_length = 0xEB14; -} - - -void -zip_init(int id, int cdb_len_setting) -{ - zip_t *dev = zip[id]; - - if (id >= ZIP_NUM) - return; - - memset(dev, 0, sizeof(zip_t)); - dev->requested_blocks = 1; - if (cdb_len_setting <= 1) - dev->cdb_len_setting = cdb_len_setting; - zip_reset_cdb_len(id); - dev->sense[0] = 0xf0; - dev->sense[7] = 10; - zip_drives[id].bus_mode = 0; - if (zip_drives[id].bus_type >= ZIP_BUS_ATAPI) - zip_drives[id].bus_mode |= 2; - if (zip_drives[id].bus_type < ZIP_BUS_SCSI) - zip_drives[id].bus_mode |= 1; - zip_log("ZIP %i: Bus type %i, bus mode %i\n", id, zip_drives[id].bus_type, zip_drives[id].bus_mode); - if (zip_drives[id].bus_type < ZIP_BUS_SCSI) - zip_set_signature(id); - dev->status = READY_STAT | DSC_STAT; - dev->pos = 0; - dev->packet_status = 0xff; - zip_sense_key = zip_asc = zip_ascq = dev->unit_attention = 0; - dev->cdb_len_setting = 0; - dev->cdb_len = 12; -} - - -static int -zip_supports_pio(int id) -{ - return (zip_drives[id].bus_mode & 1); -} - - -static int -zip_supports_dma(int id) -{ - return (zip_drives[id].bus_mode & 2); -} - - -/* Returns: 0 for none, 1 for PIO, 2 for DMA. */ -static int -zip_current_mode(int id) -{ - zip_t *dev = zip[id]; - - if (!zip_supports_pio(id) && !zip_supports_dma(id)) - return 0; - if (zip_supports_pio(id) && !zip_supports_dma(id)) { - zip_log("ZIP %i: Drive does not support DMA, setting to PIO\n", id); - return 1; - } - if (!zip_supports_pio(id) && zip_supports_dma(id)) - return 2; - if (zip_supports_pio(id) && zip_supports_dma(id)) { - zip_log("ZIP %i: Drive supports both, setting to %s\n", id, (dev->features & 1) ? "DMA" : "PIO", id); - return (dev->features & 1) ? 2 : 1; - } - - return 0; -} - - -/* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ -int -zip_ZIP_PHASE_to_scsi(uint8_t id) -{ - zip_t *dev = zip[id]; - - if (dev->status & ERR_STAT) - return SCSI_STATUS_CHECK_CONDITION; - else - return SCSI_STATUS_OK; -} - - -/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ -int -zip_atapi_phase_to_scsi(uint8_t id) -{ - zip_t *dev = zip[id]; - - if (dev->status & 8) { - switch (dev->phase & 3) { - case 0: - return 0; - case 1: - return 2; - case 2: - return 1; - case 3: - return 7; - } - } else { - if ((dev->phase & 3) == 3) - return 3; - else - return 4; - } - - return 0; -} - - -static void -zip_mode_sense_load(uint8_t id) -{ - FILE *f; - wchar_t file_name[512]; - int i; - - memset(&zip_mode_sense_pages_saved[id], 0, sizeof(mode_sense_pages_t)); - for (i = 0; i < 0x3f; i++) { - if (zip_drives[id].is_250) { - if (zip_250_mode_sense_pages_default.pages[i][1] != 0) { - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - memcpy(zip_mode_sense_pages_saved[id].pages[i], zip_250_mode_sense_pages_default_scsi.pages[i], zip_250_mode_sense_pages_default_scsi.pages[i][1] + 2); - else - memcpy(zip_mode_sense_pages_saved[id].pages[i], zip_250_mode_sense_pages_default.pages[i], zip_250_mode_sense_pages_default.pages[i][1] + 2); - } - } else { - if (zip_mode_sense_pages_default.pages[i][1] != 0) { - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - memcpy(zip_mode_sense_pages_saved[id].pages[i], zip_mode_sense_pages_default_scsi.pages[i], zip_mode_sense_pages_default_scsi.pages[i][1] + 2); - else - memcpy(zip_mode_sense_pages_saved[id].pages[i], zip_mode_sense_pages_default.pages[i], zip_mode_sense_pages_default.pages[i][1] + 2); - } - } - } - memset(file_name, 0, 512 * sizeof(wchar_t)); - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - swprintf(file_name, 512, L"scsi_zip_%02i_mode_sense_bin", id); - else - swprintf(file_name, 512, L"zip_%02i_mode_sense_bin", id); - f = plat_fopen(nvr_path(file_name), L"rb"); - if (f) - fclose(f); -} - - -static void -zip_mode_sense_save(uint8_t id) -{ - FILE *f; - wchar_t file_name[512]; - - memset(file_name, 0, 512 * sizeof(wchar_t)); - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - swprintf(file_name, 512, L"scsi_zip_%02i_mode_sense_bin", id); - else - swprintf(file_name, 512, L"zip_%02i_mode_sense_bin", id); - f = plat_fopen(nvr_path(file_name), L"wb"); - if (f) - fclose(f); -} - - -int -zip_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len) -{ - int size = 0; - - if (zip_drives[id].is_250) - size = zip_drives[id].medium_size - 1; /* IMPORTANT: What's returned is the last LBA block. */ - else - size = ZIP_SECTORS - 1; /* IMPORTANT: What's returned is the last LBA block. */ - memset(buffer, 0, 8); - buffer[0] = (size >> 24) & 0xff; - buffer[1] = (size >> 16) & 0xff; - buffer[2] = (size >> 8) & 0xff; - buffer[3] = size & 0xff; - buffer[6] = 2; /* 512 = 0x0200 */ - *len = 8; - - return 1; -} - - -/*SCSI Mode Sense 6/10*/ -static uint8_t -zip_mode_sense_read(uint8_t id, uint8_t page_control, uint8_t page, uint8_t pos) -{ - switch (page_control) { - case 0: - case 3: - if (zip_drives[id].is_250 && (page == 5) && (pos == 9) && (zip_drives[id].medium_size == ZIP_SECTORS)) - return 0x60; - return zip_mode_sense_pages_saved[id].pages[page][pos]; - break; - case 1: - if (zip_drives[id].is_250) - return zip_250_mode_sense_pages_changeable.pages[page][pos]; - else - return zip_mode_sense_pages_changeable.pages[page][pos]; - break; - case 2: - if (zip_drives[id].is_250) { - if ((page == 5) && (pos == 9) && (zip_drives[id].medium_size == ZIP_SECTORS)) - return 0x60; - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - return zip_250_mode_sense_pages_default_scsi.pages[page][pos]; - else - return zip_250_mode_sense_pages_default.pages[page][pos]; - } else { - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - return zip_mode_sense_pages_default_scsi.pages[page][pos]; - else - return zip_mode_sense_pages_default.pages[page][pos]; - } - break; - } - - return 0; -} - - -static uint32_t -zip_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len) -{ - zip_t *dev = zip[id]; - - uint64_t page_flags; - uint8_t page_control = (type >> 6) & 3; - - if (zip_drives[id].is_250) - page_flags = zip_250_mode_sense_page_flags; - else - page_flags = zip_mode_sense_page_flags; - - int i = 0; - int j = 0; - - uint8_t msplen; - - type &= 0x3f; - - if (block_descriptor_len) { - if (zip_drives[id].is_250) { - buf[pos++] = ((zip_drives[id].medium_size >> 24) & 0xff); - buf[pos++] = ((zip_drives[id].medium_size >> 16) & 0xff); - buf[pos++] = ((zip_drives[id].medium_size >> 8) & 0xff); - buf[pos++] = ( zip_drives[id].medium_size & 0xff); - } else { - buf[pos++] = ((ZIP_SECTORS >> 24) & 0xff); - buf[pos++] = ((ZIP_SECTORS >> 16) & 0xff); - buf[pos++] = ((ZIP_SECTORS >> 8) & 0xff); - buf[pos++] = ( ZIP_SECTORS & 0xff); - } - buf[pos++] = 0; /* Reserved. */ - buf[pos++] = 0; /* Block length (0x200 = 512 bytes). */ - buf[pos++] = 2; - buf[pos++] = 0; - } - - for (i = 0; i < 0x40; i++) { - if ((type == GPMODE_ALL_PAGES) || (type == i)) { - if (page_flags & (1LL << dev->current_page_code)) { - buf[pos++] = zip_mode_sense_read(id, page_control, i, 0); - msplen = zip_mode_sense_read(id, page_control, i, 1); - buf[pos++] = msplen; - zip_log("ZIP %i: MODE SENSE: Page [%02X] length %i\n", id, i, msplen); - for (j = 0; j < msplen; j++) - buf[pos++] = zip_mode_sense_read(id, page_control, i, 2 + j); - } - } - } - - return pos; -} - - -static void -zip_update_request_length(uint8_t id, int len, int block_len) -{ - zip_t *dev = zip[id]; - uint32_t bt, min_len = 0; - - dev->max_transfer_len = dev->request_length; - - /* For media access commands, make sure the requested DRQ length matches the block length. */ - switch (dev->current_cdb[0]) { - case 0x08: - case 0x28: - case 0xa8: - /* Make sure total length is not bigger than sum of the lengths of - all the requested blocks. */ - bt = (dev->requested_blocks * block_len); - if (len > bt) - len = bt; - - min_len = block_len; - - if (len <= block_len) { - /* Total length is less or equal to block length. */ - if (dev->max_transfer_len < block_len) { - /* Transfer a minimum of (block size) bytes. */ - dev->max_transfer_len = block_len; - dev->packet_len = block_len; - break; - } - } - default: - dev->packet_len = len; - break; - } - /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ - if ((dev->max_transfer_len & 1) && (dev->max_transfer_len < len)) - dev->max_transfer_len &= 0xfffe; - /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ - if (!dev->max_transfer_len) - dev->max_transfer_len = 65534; - - if ((len <= dev->max_transfer_len) && (len >= min_len)) - dev->request_length = dev->max_transfer_len = len; - else if (len > dev->max_transfer_len) - dev->request_length = dev->max_transfer_len; - - return; -} - - -static void -zip_command_bus(uint8_t id) -{ - zip_t *dev = zip[id]; - - dev->status = BUSY_STAT; - dev->phase = 1; - dev->pos = 0; - dev->callback = 1LL * ZIP_TIME; - zip_set_callback(id); -} - - -static void -zip_command_common(uint8_t id) -{ - zip_t *dev = zip[id]; - - double bytes_per_second, period; - double dusec; - - dev->status = BUSY_STAT; - dev->phase = 1; - dev->pos = 0; - if (dev->packet_status == ZIP_PHASE_COMPLETE) { - zip_phase_callback(id); - dev->callback = 0LL; - } else { - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { - dev->callback = -1LL; /* Speed depends on SCSI controller */ - return; - } else { - if (zip_current_mode(id) == 2) - bytes_per_second = 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ - else - bytes_per_second = 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ - } - - period = 1000000.0 / bytes_per_second; - dusec = (double) TIMER_USEC; - dusec = dusec * period * (double) (dev->packet_len); - dev->callback = ((int64_t) dusec); - } - - zip_set_callback(id); -} - - -static void -zip_command_complete(uint8_t id) -{ - zip_t *dev = zip[id]; - - dev->packet_status = ZIP_PHASE_COMPLETE; - zip_command_common(id); -} - - -static void -zip_command_read(uint8_t id) -{ - zip_t *dev = zip[id]; - - dev->packet_status = ZIP_PHASE_DATA_IN; - zip_command_common(id); - dev->total_read = 0; -} - - -static void -zip_command_read_dma(uint8_t id) -{ - zip_t *dev = zip[id]; - - dev->packet_status = ZIP_PHASE_DATA_IN_DMA; - zip_command_common(id); - dev->total_read = 0; -} - -static void -zip_command_write(uint8_t id) -{ - zip_t *dev = zip[id]; - - dev->packet_status = ZIP_PHASE_DATA_OUT; - zip_command_common(id); -} - - -static void -zip_command_write_dma(uint8_t id) -{ - zip_t *dev = zip[id]; - - dev->packet_status = ZIP_PHASE_DATA_OUT_DMA; - zip_command_common(id); -} - - -/* id = Current ZIP device ID; - len = Total transfer length; - block_len = Length of a single block (why does it matter?!); - alloc_len = Allocated transfer length; - direction = Transfer direction (0 = read from host, 1 = write to host). */ -static void -zip_data_command_finish(uint8_t id, int len, int block_len, int alloc_len, int direction) -{ - zip_t *dev = zip[id]; - - zip_log("ZIP %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); - dev->pos=0; - if (alloc_len >= 0) { - if (alloc_len < len) - len = alloc_len; - } - if ((len == 0) || (zip_current_mode(id) == 0)) { - if (zip_drives[id].bus_type != ZIP_BUS_SCSI) - dev->packet_len = 0; - - zip_command_complete(id); - } else { - if (zip_current_mode(id) == 2) { - if (zip_drives[id].bus_type != ZIP_BUS_SCSI) - dev->packet_len = alloc_len; - - if (direction == 0) - zip_command_read_dma(id); - else - zip_command_write_dma(id); - } else { - zip_update_request_length(id, len, block_len); - if (direction == 0) - zip_command_read(id); - else - zip_command_write(id); - } - } - - zip_log("ZIP %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase); -} - - -static void -zip_sense_clear(int id, int command) -{ - zip_t *dev = zip[id]; - - dev->previous_command = command; - zip_sense_key = zip_asc = zip_ascq = 0; -} - - -static void -zip_set_phase(uint8_t id, uint8_t phase) -{ - uint8_t scsi_id = zip_drives[id].scsi_device_id; - uint8_t scsi_lun = zip_drives[id].scsi_device_lun; - - if (zip_drives[id].bus_type != ZIP_BUS_SCSI) - return; - - SCSIDevices[scsi_id][scsi_lun].Phase = phase; -} - - -static void -zip_cmd_error(uint8_t id) -{ - zip_t *dev = zip[id]; - - zip_set_phase(id, SCSI_PHASE_STATUS); - dev->error = ((zip_sense_key & 0xf) << 4) | ABRT_ERR; - if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; - dev->packet_status = 0x80; - dev->callback = 50LL * ZIP_TIME; - zip_set_callback(id); - zip_log("ZIP %i: [%02X] ERROR: %02X/%02X/%02X\n", id, dev->current_cdb[0], zip_sense_key, zip_asc, zip_ascq); -} - - -static void -zip_unit_attention(uint8_t id) -{ - zip_t *dev = zip[id]; - - zip_set_phase(id, SCSI_PHASE_STATUS); - dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; - if (dev->unit_attention) - dev->error |= MCR_ERR; - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->pos = 0; - dev->packet_status = 0x80; - dev->callback = 50LL * ZIP_TIME; - zip_set_callback(id); - zip_log("ZIP %i: UNIT ATTENTION\n", id); -} - - -static void -zip_bus_master_error(uint8_t id) -{ - zip_sense_key = zip_asc = zip_ascq = 0; - zip_cmd_error(id); -} - - -static void -zip_not_ready(uint8_t id) -{ - zip_sense_key = SENSE_NOT_READY; - zip_asc = ASC_MEDIUM_NOT_PRESENT; - zip_ascq = 0; - zip_cmd_error(id); -} - - -static void -zip_write_protected(uint8_t id) -{ - zip_sense_key = SENSE_UNIT_ATTENTION; - zip_asc = ASC_WRITE_PROTECTED; - zip_ascq = 0; - zip_cmd_error(id); -} - - -static void -zip_invalid_lun(uint8_t id) -{ - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_INV_LUN; - zip_ascq = 0; - zip_cmd_error(id); -} - - -static void -zip_illegal_opcode(uint8_t id) -{ - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_ILLEGAL_OPCODE; - zip_ascq = 0; - zip_cmd_error(id); -} - - -static void -zip_lba_out_of_range(uint8_t id) -{ - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_LBA_OUT_OF_RANGE; - zip_ascq = 0; - zip_cmd_error(id); -} - - -static void -zip_invalid_field(uint8_t id) -{ - zip_t *dev = zip[id]; - - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_INV_FIELD_IN_CMD_PACKET; - zip_ascq = 0; - zip_cmd_error(id); - dev->status = 0x53; -} - - -static void -zip_invalid_field_pl(uint8_t id) -{ - zip_t *dev = zip[id]; - - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; - zip_ascq = 0; - zip_cmd_error(id); - dev->status = 0x53; -} - - -static void -zip_data_phase_error(uint8_t id) -{ - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_DATA_PHASE_ERROR; - zip_ascq = 0; - zip_cmd_error(id); -} - - -static int -zip_blocks(uint8_t id, uint32_t *len, int first_batch, int out) -{ - zip_t *dev = zip[id]; - - dev->data_pos = 0; - - *len = 0; - - if (!dev->sector_len) { - zip_command_complete(id); - return -1; - } - - zip_log("%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", dev->requested_blocks, dev->sector_pos); - - if (dev->sector_pos >= zip_drives[id].medium_size) { - zip_log("ZIP %i: Trying to %s beyond the end of disk\n", id, out ? "write" : "read"); - zip_lba_out_of_range(id); - return 0; - } - - *len = dev->requested_blocks << 9; - - fseek(zip_drives[id].f, zip_drives[id].base + (dev->sector_pos << 9), SEEK_SET); - if (out) - fwrite(zipbufferb, 1, *len, zip_drives[id].f); - else - fread(zipbufferb, 1, *len, zip_drives[id].f); - - zip_log("%s %i bytes of blocks...\n", out ? "Written" : "Read", *len); - - dev->sector_pos += dev->requested_blocks; - dev->sector_len -= dev->requested_blocks; - - return 1; -} - - -void -zip_insert(uint8_t id) -{ - zip_t *dev = zip[id]; - - dev->unit_attention = 1; -} - - -/*SCSI Sense Initialization*/ -void -zip_sense_code_ok(uint8_t id) -{ - zip_sense_key = SENSE_NONE; - zip_asc = 0; - zip_ascq = 0; -} - - -static int -zip_pre_execution_check(uint8_t id, uint8_t *cdb) -{ - zip_t *dev = zip[id]; - int ready = 0; - - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { - if (((dev->request_length >> 5) & 7) != zip_drives[id].scsi_device_lun) { - zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", id, ((dev->request_length >> 5) & 7)); - zip_invalid_lun(id); - return 0; - } - } - - if (!(zip_command_flags[cdb[0]] & IMPLEMENTED)) { - zip_log("ZIP %i: Attempting to execute unknown command %02X over %s\n", id, cdb[0], - (zip_drives[id].bus_type == ZIP_BUS_SCSI) ? "SCSI" : "ATAPI"); - - zip_illegal_opcode(id); - return 0; - } - - if ((zip_drives[id].bus_type < ZIP_BUS_SCSI) && (zip_command_flags[cdb[0]] & SCSI_ONLY)) { - zip_log("ZIP %i: Attempting to execute SCSI-only command %02X over ATAPI\n", id, cdb[0]); - zip_illegal_opcode(id); - return 0; - } - - if ((zip_drives[id].bus_type == ZIP_BUS_SCSI) && (zip_command_flags[cdb[0]] & ATAPI_ONLY)) { - zip_log("ZIP %i: Attempting to execute ATAPI-only command %02X over SCSI\n", id, cdb[0]); - zip_illegal_opcode(id); - return 0; - } - - ready = (zip_drives[id].f != NULL); - - /* If the drive is not ready, there is no reason to keep the - UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - if (!ready && dev->unit_attention) - dev->unit_attention = 0; - - /* If the UNIT ATTENTION condition is set and the command does not allow - execution under it, error out and report the condition. */ - if (dev->unit_attention == 1) { - /* Only increment the unit attention phase if the command can not pass through it. */ - if (!(zip_command_flags[cdb[0]] & ALLOW_UA)) { - /* zip_log("ZIP %i: Unit attention now 2\n", id); */ - dev->unit_attention = 2; - zip_log("ZIP %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", id, cdb[0]); - zip_unit_attention(id); - return 0; - } - } else if (dev->unit_attention == 2) { - if (cdb[0] != GPCMD_REQUEST_SENSE) { - /* zip_log("ZIP %i: Unit attention now 0\n", id); */ - dev->unit_attention = 0; - } - } - - /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* - the UNIT ATTENTION condition if it's set. */ - if (cdb[0] != GPCMD_REQUEST_SENSE) - zip_sense_clear(id, cdb[0]); - - /* Next it's time for NOT READY. */ - if (!ready) - dev->media_status = MEC_MEDIA_REMOVAL; - else - dev->media_status = (dev->unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE; - - if ((zip_command_flags[cdb[0]] & CHECK_READY) && !ready) { - zip_log("ZIP %i: Not ready (%02X)\n", id, cdb[0]); - zip_not_ready(id); - return 0; - } - - zip_log("ZIP %i: Continuing with command %02X\n", id, cdb[0]); - - return 1; -} - - -static void -zip_seek(uint8_t id, uint32_t pos) -{ - zip_t *dev = zip[id]; - - /* zip_log("ZIP %i: Seek %08X\n", id, pos); */ - dev->sector_pos = pos; -} - - -static void -zip_rezero(uint8_t id) -{ - zip_t *dev = zip[id]; - - dev->sector_pos = dev->sector_len = 0; - zip_seek(id, 0); -} - - -void -zip_reset(uint8_t id) -{ - zip_t *dev = zip[id]; - - zip_rezero(id); - dev->status = 0; - dev->callback = 0LL; - zip_set_callback(id); - dev->packet_status = 0xff; - dev->unit_attention = 0; -} - - -static void -zip_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length, int desc) -{ - zip_t *dev = zip[id]; - - /*Will return 18 bytes of 0*/ - if (alloc_length != 0) { - memset(buffer, 0, alloc_length); - if (!desc) - memcpy(buffer, dev->sense, alloc_length); - else { - buffer[1] = zip_sense_key; - buffer[2] = zip_asc; - buffer[3] = zip_ascq; - } - } - - buffer[0] = desc ? 0x72 : 0x70; - - if (dev->unit_attention && (zip_sense_key == 0)) { - buffer[desc ? 1 : 2]=SENSE_UNIT_ATTENTION; - buffer[desc ? 2 : 12]=ASC_MEDIUM_MAY_HAVE_CHANGED; - buffer[desc ? 3 : 13]=0; - } - - zip_log("ZIP %i: Reporting sense: %02X %02X %02X\n", id, buffer[2], buffer[12], buffer[13]); - - if (buffer[desc ? 1 : 2] == SENSE_UNIT_ATTENTION) { - /* If the last remaining sense is unit attention, clear - that condition. */ - dev->unit_attention = 0; - } - - /* Clear the sense stuff as per the spec. */ - zip_sense_clear(id, GPCMD_REQUEST_SENSE); -} - - -void -zip_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length) -{ - zip_t *dev = zip[id]; - int ready = 0; - - ready = (zip_drives[id].f != NULL); - - if (!ready && dev->unit_attention) { - /* If the drive is not ready, there is no reason to keep the - UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - dev->unit_attention = 0; - } - - /* Do *NOT* advance the unit attention phase. */ - - zip_request_sense(id, buffer, alloc_length, 0); -} - - -static void -zip_set_buf_len(uint8_t id, int32_t *BufLen, uint32_t *src_len) -{ - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { - if (*BufLen == -1) - *BufLen = *src_len; - else { - *BufLen = MIN(*src_len, *BufLen); - *src_len = *BufLen; - } - zip_log("ZIP %i: Actual transfer length: %i\n", id, *BufLen); - } -} - - -static void -zip_buf_alloc(uint8_t id, uint32_t len) -{ - zip_t *dev = zip[id]; - - zip_log("ZIP %i: Allocated buffer length: %i\n", id, len); - zipbufferb = (uint8_t *) malloc(len); -} - - -static void -zip_buf_free(uint8_t id) -{ - zip_t *dev = zip[id]; - - if (zipbufferb) { - zip_log("ZIP %i: Freeing buffer...\n", id); - free(zipbufferb); - zipbufferb = NULL; - } -} - - -void -zip_command(uint8_t id, uint8_t *cdb) -{ - int pos = 0, block_desc = 0; - int ret; - uint32_t len, max_len; - uint32_t alloc_length, i = 0; - unsigned size_idx, idx = 0; - unsigned preamble_len; - int32_t blen = 0; - int32_t *BufLen; - - zip_t *dev = zip[id]; - - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { - BufLen = &SCSIDevices[zip_drives[id].scsi_device_id][zip_drives[id].scsi_device_lun].BufferLength; - dev->status &= ~ERR_STAT; - } else { - BufLen = &blen; - dev->error = 0; - } - - dev->packet_len = 0; - dev->request_pos = 0; - - dev->data_pos = 0; - - memcpy(dev->current_cdb, cdb, dev->cdb_len); - - if (cdb[0] != 0) { - zip_log("ZIP %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", id, cdb[0], zip_sense_key, zip_asc, zip_ascq, dev->unit_attention); - zip_log("ZIP %i: Request length: %04X\n", id, dev->request_length); - - zip_log("ZIP %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", id, - cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], - cdb[8], cdb[9], cdb[10], cdb[11]); - } - - dev->sector_len = 0; - - zip_set_phase(id, SCSI_PHASE_STATUS); - - /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ - if (zip_pre_execution_check(id, cdb) == 0) - return; - - switch (cdb[0]) { - case GPCMD_SEND_DIAGNOSTIC: - if (!(cdb[1] & (1 << 2))) { - zip_invalid_field(id); - return; - } - case GPCMD_SCSI_RESERVE: - case GPCMD_SCSI_RELEASE: - case GPCMD_TEST_UNIT_READY: - zip_set_phase(id, SCSI_PHASE_STATUS); - zip_command_complete(id); - break; - - case GPCMD_FORMAT_UNIT: - if ((zip_drives[id].bus_type == ZIP_BUS_SCSI) && zip_drives[id].read_only) - { - zip_write_protected(id); - return; - } - - zip_set_phase(id, SCSI_PHASE_STATUS); - zip_command_complete(id); - break; - - case GPCMD_IOMEGA_SENSE: - zip_set_phase(id, SCSI_PHASE_DATA_IN); - max_len = cdb[4]; - zip_buf_alloc(id, 256); - zip_set_buf_len(id, BufLen, &max_len); - memset(zipbufferb, 0, 256); - if (cdb[2] == 1) { - /* This page is related to disk health status - setting - this page to 0 makes disk health read as "marginal". */ - zipbufferb[0] = 0x58; - zipbufferb[1] = 0x00; - for (i = 0x00; i < 0x58; i++) - zipbufferb[i + 0x02] = 0xff; - } else if (cdb[2] == 2) { - zipbufferb[0] = 0x3d; - zipbufferb[1] = 0x00; - for (i = 0x00; i < 0x13; i++) - zipbufferb[i + 0x02] = 0x00; - zipbufferb[0x15] = 0x00; - if (zip_drives[id].read_only) - zipbufferb[0x15] |= 0x02; - for (i = 0x00; i < 0x27; i++) - zipbufferb[i + 0x16] = 0x00; - } else { - zip_invalid_field(id); - zip_buf_free(id); - return; - } - zip_data_command_finish(id, 18, 18, cdb[4], 0); - break; - - case GPCMD_REZERO_UNIT: - dev->sector_pos = dev->sector_len = 0; - zip_seek(id, 0); - zip_set_phase(id, SCSI_PHASE_STATUS); - break; - - case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ - zip_set_phase(id, SCSI_PHASE_DATA_IN); - max_len = cdb[4]; - zip_buf_alloc(id, 256); - zip_set_buf_len(id, BufLen, &max_len); - len = (cdb[1] & 1) ? 8 : 18; - zip_request_sense(id, zipbufferb, max_len, cdb[1] & 1); - zip_data_command_finish(id, len, len, cdb[4], 0); - break; - - case GPCMD_MECHANISM_STATUS: - zip_set_phase(id, SCSI_PHASE_DATA_IN); - len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - - zip_buf_alloc(id, 8); - - zip_set_buf_len(id, BufLen, &len); - - memset(zipbufferb, 0, 8); - zipbufferb[5] = 1; - - zip_data_command_finish(id, 8, 8, len, 0); - break; - - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - zip_set_phase(id, SCSI_PHASE_DATA_IN); - alloc_length = 512; - - switch(cdb[0]) { - case GPCMD_READ_6: - dev->sector_len = cdb[4]; - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - zip_log("ZIP %i: Length: %i, LBA: %i\n", id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_READ_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - zip_log("ZIP %i: Length: %i, LBA: %i\n", id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } - - if (!dev->sector_len) { - zip_set_phase(id, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", id); */ - dev->packet_status = ZIP_PHASE_COMPLETE; - dev->callback = 20LL * ZIP_TIME; - zip_set_callback(id); - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - zip_buf_alloc(id, dev->packet_len); - - ret = zip_blocks(id, &alloc_length, 1, 0); - if (ret <= 0) { - zip_buf_free(id); - return; - } - - dev->requested_blocks = max_len; - dev->packet_len = alloc_length; - - zip_set_buf_len(id, BufLen, &dev->packet_len); - - zip_data_command_finish(id, alloc_length, 512, alloc_length, 0); - - dev->all_blocks_total = dev->block_total; - if (dev->packet_status != ZIP_PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | id, 1); - else - ui_sb_update_icon(SB_ZIP | id, 0); - return; - - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - if (!(cdb[1] & 2)) { - zip_set_phase(id, SCSI_PHASE_STATUS); - zip_command_complete(id); - break; - } - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - zip_set_phase(id, SCSI_PHASE_DATA_OUT); - alloc_length = 512; - - if ((zip_drives[id].bus_type == ZIP_BUS_SCSI) && zip_drives[id].read_only) { - zip_write_protected(id); - return; - } - - switch(cdb[0]) { - case GPCMD_VERIFY_6: - case GPCMD_WRITE_6: - dev->sector_len = cdb[4]; - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - break; - case GPCMD_VERIFY_10: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - zip_log("ZIP %i: Length: %i, LBA: %i\n", id, dev->sector_len, dev->sector_pos); - break; - case GPCMD_VERIFY_12: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } - - if (zip_drives[id].is_250) { - if ((dev->sector_pos >= zip_drives[id].medium_size) || - ((dev->sector_pos + dev->sector_len - 1) >= zip_drives[id].medium_size)) { - zip_lba_out_of_range(id); - return; - } - } else { - if ((dev->sector_pos >= ZIP_SECTORS) || - ((dev->sector_pos + dev->sector_len - 1) >= ZIP_SECTORS)) { - zip_lba_out_of_range(id); - return; - } - } - - if (!dev->sector_len) { - zip_set_phase(id, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", id); */ - dev->packet_status = ZIP_PHASE_COMPLETE; - dev->callback = 20LL * ZIP_TIME; - zip_set_callback(id); - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're writing all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - zip_buf_alloc(id, dev->packet_len); - - dev->requested_blocks = max_len; - dev->packet_len = max_len << 9; - - zip_set_buf_len(id, BufLen, &dev->packet_len); - - zip_data_command_finish(id, dev->packet_len, 512, dev->packet_len, 1); - - dev->all_blocks_total = dev->block_total; - if (dev->packet_status != ZIP_PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | id, 1); - else - ui_sb_update_icon(SB_ZIP | id, 0); - return; - - case GPCMD_WRITE_SAME_10: - zip_set_phase(id, SCSI_PHASE_DATA_OUT); - alloc_length = 512; - - if ((cdb[1] & 6) == 6) { - zip_invalid_field(id); - return; - } - - if ((zip_drives[id].bus_type == ZIP_BUS_SCSI) && zip_drives[id].read_only) { - zip_write_protected(id); - return; - } - - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - - if (zip_drives[id].is_250) { - if ((dev->sector_pos >= zip_drives[id].medium_size) || - ((dev->sector_pos + dev->sector_len - 1) >= zip_drives[id].medium_size)) { - zip_lba_out_of_range(id); - return; - } - } else { - if ((dev->sector_pos >= ZIP_SECTORS) || - ((dev->sector_pos + dev->sector_len - 1) >= ZIP_SECTORS)) { - zip_lba_out_of_range(id); - return; - } - } - - if (!dev->sector_len) { - zip_set_phase(id, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", id); */ - dev->packet_status = ZIP_PHASE_COMPLETE; - dev->callback = 20LL * ZIP_TIME; - zip_set_callback(id); - break; - } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're writing all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - zip_buf_alloc(id, dev->packet_len); - - dev->requested_blocks = max_len; - dev->packet_len = alloc_length; - - zip_set_buf_len(id, BufLen, &dev->packet_len); - - zip_data_command_finish(id, dev->packet_len, 512, dev->packet_len, 1); - - dev->all_blocks_total = dev->block_total; - if (dev->packet_status != ZIP_PHASE_COMPLETE) - ui_sb_update_icon(SB_ZIP | id, 1); - else - ui_sb_update_icon(SB_ZIP | id, 0); - return; - - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - zip_set_phase(id, SCSI_PHASE_DATA_IN); - - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; - else - block_desc = 0; - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = cdb[4]; - zip_buf_alloc(id, 256); - } else { - len = (cdb[8] | (cdb[7] << 8)); - zip_buf_alloc(id, 65536); - } - - dev->current_page_code = cdb[2] & 0x3F; - zip_log("Mode sense page: %02X\n", dev->current_page_code); - - if (!(zip_mode_sense_page_flags & (1LL << dev->current_page_code))) { - zip_invalid_field(id); - zip_buf_free(id); - return; - } - - memset(zipbufferb, 0, len); - alloc_length = len; - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = zip_mode_sense(id, zipbufferb, 4, cdb[2], block_desc); - len = MIN(len, alloc_length); - zipbufferb[0] = len - 1; - zipbufferb[1] = 0; - if (block_desc) - zipbufferb[3] = 8; - } else { - len = zip_mode_sense(id, zipbufferb, 8, cdb[2], block_desc); - len = MIN(len, alloc_length); - zipbufferb[0]=(len - 2) >> 8; - zipbufferb[1]=(len - 2) & 255; - zipbufferb[2] = 0; - if (block_desc) { - zipbufferb[6] = 0; - zipbufferb[7] = 8; - } - } - - zip_set_buf_len(id, BufLen, &len); - - zip_log("ZIP %i: Reading mode page: %02X...\n", id, cdb[2]); - - zip_data_command_finish(id, len, len, alloc_length, 0); - return; - - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - zip_set_phase(id, SCSI_PHASE_DATA_OUT); - - if (cdb[0] == GPCMD_MODE_SELECT_6) { - len = cdb[4]; - zip_buf_alloc(id, 256); - } else { - len = (cdb[7] << 8) | cdb[8]; - zip_buf_alloc(id, 65536); - } - - zip_set_buf_len(id, BufLen, &len); - - dev->total_length = len; - dev->do_page_save = cdb[1] & 1; - - dev->current_page_pos = 0; - - zip_data_command_finish(id, len, len, len, 1); - return; - - case GPCMD_START_STOP_UNIT: - zip_set_phase(id, SCSI_PHASE_STATUS); - - switch(cdb[4] & 3) { - case 0: /* Stop the disc. */ - zip_eject(id); /* The Iomega Windows 9x drivers require this. */ - break; - case 1: /* Start the disc and read the TOC. */ - break; - case 2: /* Eject the disc if possible. */ - /* zip_eject(id); */ - break; - case 3: /* Load the disc (close tray). */ - zip_reload(id); - break; - } - - zip_command_complete(id); - break; - - case GPCMD_INQUIRY: - zip_set_phase(id, SCSI_PHASE_DATA_IN); - - max_len = cdb[3]; - max_len <<= 8; - max_len |= cdb[4]; - - zip_buf_alloc(id, 65536); - - if (cdb[1] & 1) { - preamble_len = 4; - size_idx = 3; - - zipbufferb[idx++] = 05; - zipbufferb[idx++] = cdb[2]; - zipbufferb[idx++] = 0; - - idx++; - - switch (cdb[2]) { - case 0x00: - zipbufferb[idx++] = 0x00; - zipbufferb[idx++] = 0x83; - break; - case 0x83: - if (idx + 24 > max_len) { - zip_data_phase_error(id); - zip_buf_free(id); - return; - } - - zipbufferb[idx++] = 0x02; - zipbufferb[idx++] = 0x00; - zipbufferb[idx++] = 0x00; - zipbufferb[idx++] = 20; - ide_padstr8(zipbufferb + idx, 20, "53R141"); /* Serial */ - idx += 20; - - if (idx + 72 > cdb[4]) - goto atapi_out; - zipbufferb[idx++] = 0x02; - zipbufferb[idx++] = 0x01; - zipbufferb[idx++] = 0x00; - zipbufferb[idx++] = 68; - ide_padstr8(zipbufferb + idx, 8, "IOMEGA "); /* Vendor */ - idx += 8; - if (zip_drives[id].is_250) - ide_padstr8(zipbufferb + idx, 40, "ZIP 250 "); /* Product */ - else - ide_padstr8(zipbufferb + idx, 40, "ZIP 100 "); /* Product */ - idx += 40; - ide_padstr8(zipbufferb + idx, 20, "53R141"); /* Product */ - idx += 20; - break; - default: - zip_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - zip_invalid_field(id); - zip_buf_free(id); - return; - } - } else { - preamble_len = 5; - size_idx = 4; - - memset(zipbufferb, 0, 8); - if (cdb[1] & 0xe0) - zipbufferb[0] = 0x60; /*No physical device on this LUN*/ - else - zipbufferb[0] = 0x00; /*Hard disk*/ - zipbufferb[1] = 0x80; /*Removable*/ - if (zip_drives[id].is_250) { - zipbufferb[2] = (zip_drives[id].bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ - zipbufferb[3] = (zip_drives[id].bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21; - } else { - zipbufferb[2] = (zip_drives[id].bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ - zipbufferb[3] = (zip_drives[id].bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21; - } - zipbufferb[4] = 31; - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { - zipbufferb[6] = 1; /* 16-bit transfers supported */ - zipbufferb[7] = 0x20; /* Wide bus supported */ - } - - ide_padstr8(zipbufferb + 8, 8, "IOMEGA "); /* Vendor */ - if (zip_drives[id].is_250) { - ide_padstr8(zipbufferb + 16, 16, "ZIP 250 "); /* Product */ - ide_padstr8(zipbufferb + 32, 4, "42.S"); /* Revision */ - if (max_len >= 44) - ide_padstr8(zipbufferb + 36, 8, "08/08/01"); /* Date? */ - if (max_len >= 122) - ide_padstr8(zipbufferb + 96, 26, "(c) Copyright IOMEGA 2000 "); /* Copyright string */ - } else { - ide_padstr8(zipbufferb + 16, 16, "ZIP 100 "); /* Product */ - ide_padstr8(zipbufferb + 32, 4, "E.08"); /* Revision */ - } - idx = 36; - - if (max_len == 96) { - zipbufferb[4] = 91; - idx = 96; - } else if (max_len == 128) { - zipbufferb[4] = 0x75; - idx = 128; - } - } - -atapi_out: - zipbufferb[size_idx] = idx - preamble_len; - len=idx; - - len = MIN(len, max_len); - zip_set_buf_len(id, BufLen, &len); - - zip_data_command_finish(id, len, len, max_len, 0); - break; - - case GPCMD_PREVENT_REMOVAL: - zip_set_phase(id, SCSI_PHASE_STATUS); - zip_command_complete(id); - break; - - case GPCMD_SEEK_6: - case GPCMD_SEEK_10: - zip_set_phase(id, SCSI_PHASE_STATUS); - - switch(cdb[0]) { - case GPCMD_SEEK_6: - pos = (cdb[2] << 8) | cdb[3]; - break; - case GPCMD_SEEK_10: - pos = (cdb[2] << 24) | (cdb[3]<<16) | (cdb[4]<<8) | cdb[5]; - break; - } - zip_seek(id, pos); - zip_command_complete(id); - break; - - case GPCMD_READ_CDROM_CAPACITY: - zip_set_phase(id, SCSI_PHASE_DATA_IN); - - zip_buf_alloc(id, 8); - - if (zip_read_capacity(id, dev->current_cdb, zipbufferb, &len) == 0) { - zip_buf_free(id); - return; - } - - zip_set_buf_len(id, BufLen, &len); - - zip_data_command_finish(id, len, len, len, 0); - break; - - case GPCMD_IOMEGA_EJECT: - zip_set_phase(id, SCSI_PHASE_STATUS); - zip_eject(id); - zip_command_complete(id); - break; - - case GPCMD_READ_FORMAT_CAPACITIES: - len = (cdb[7] << 8) | cdb[8]; - - zip_buf_alloc(id, len); - memset(zipbufferb, 0, len); - - pos = 0; - - /* List header */ - zipbufferb[pos++] = 0; - zipbufferb[pos++] = 0; - zipbufferb[pos++] = 0; - if (zip_drives[id].f != NULL) - zipbufferb[pos++] = 16; - else - zipbufferb[pos++] = 8; - - /* Current/Maximum capacity header */ - if (zip_drives[id].is_250) { - if (zip_drives[id].f != NULL) { - zipbufferb[pos++] = (zip_drives[id].medium_size >> 24) & 0xff; - zipbufferb[pos++] = (zip_drives[id].medium_size >> 16) & 0xff; - zipbufferb[pos++] = (zip_drives[id].medium_size >> 8) & 0xff; - zipbufferb[pos++] = zip_drives[id].medium_size & 0xff; - zipbufferb[pos++] = 2; /* Current medium capacity */ - } else { - zipbufferb[pos++] = (ZIP_250_SECTORS >> 24) & 0xff; - zipbufferb[pos++] = (ZIP_250_SECTORS >> 16) & 0xff; - zipbufferb[pos++] = (ZIP_250_SECTORS >> 8) & 0xff; - zipbufferb[pos++] = ZIP_250_SECTORS & 0xff; - zipbufferb[pos++] = 3; /* Maximum medium capacity */ - } - } else { - zipbufferb[pos++] = (ZIP_SECTORS >> 24) & 0xff; - zipbufferb[pos++] = (ZIP_SECTORS >> 16) & 0xff; - zipbufferb[pos++] = (ZIP_SECTORS >> 8) & 0xff; - zipbufferb[pos++] = ZIP_SECTORS & 0xff; - if (zip_drives[id].f != NULL) - zipbufferb[pos++] = 2; - else - zipbufferb[pos++] = 3; - } - - zipbufferb[pos++] = 512 >> 16; - zipbufferb[pos++] = 512 >> 8; - zipbufferb[pos++] = 512 & 0xff; - - if (zip_drives[id].f != NULL) { - /* Formattable capacity descriptor */ - zipbufferb[pos++] = (zip_drives[id].medium_size >> 24) & 0xff; - zipbufferb[pos++] = (zip_drives[id].medium_size >> 16) & 0xff; - zipbufferb[pos++] = (zip_drives[id].medium_size >> 8) & 0xff; - zipbufferb[pos++] = zip_drives[id].medium_size & 0xff; - zipbufferb[pos++] = 0; - zipbufferb[pos++] = 512 >> 16; - zipbufferb[pos++] = 512 >> 8; - zipbufferb[pos++] = 512 & 0xff; - } - - zip_set_buf_len(id, BufLen, &len); - - zip_data_command_finish(id, len, len, len, 0); - break; - - default: - zip_illegal_opcode(id); - break; - } - - /* zip_log("ZIP %i: Phase: %02X, request length: %i\n", dev->phase, dev->request_length); */ - - if (zip_atapi_phase_to_scsi(id) == SCSI_PHASE_STATUS) - zip_buf_free(id); -} - - -/* The command second phase function, needed for Mode Select. */ -static uint8_t -zip_phase_data_out(uint8_t id) -{ - zip_t *dev = zip[id]; - - uint16_t block_desc_len; - uint16_t pos; - - uint8_t error = 0; - uint8_t page, page_len; - - uint16_t i = 0; - - uint8_t hdr_len, val, old_val, ch; - - uint32_t last_to_write = 0, len = 0; - uint32_t c, h, s; - - switch(dev->current_cdb[0]) { - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - break; - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - if (dev->requested_blocks > 0) - zip_blocks(id, &len, 1, 1); - break; - case GPCMD_WRITE_SAME_10: - if (!dev->current_cdb[7] && !dev->current_cdb[8]) { - if (zip_drives[id].is_250) - last_to_write = (zip_drives[id].medium_size - 1); - else - last_to_write = (ZIP_SECTORS - 1); - } else - last_to_write = dev->sector_pos + dev->sector_len - 1; - - for (i = dev->sector_pos; i <= last_to_write; i++) { - if (dev->current_cdb[1] & 2) { - zipbufferb[0] = (i >> 24) & 0xff; - zipbufferb[1] = (i >> 16) & 0xff; - zipbufferb[2] = (i >> 8) & 0xff; - zipbufferb[3] = i & 0xff; - } else if (dev->current_cdb[1] & 4) { - /* CHS are 96,1,2048 (ZIP 100) and 239,1,2048 (ZIP 250) */ - s = (i % 2048); - h = ((i - s) / 2048) % 1; - c = ((i - s) / 2048) / 1; - zipbufferb[0] = (c >> 16) & 0xff; - zipbufferb[1] = (c >> 8) & 0xff; - zipbufferb[2] = c & 0xff; - zipbufferb[3] = h & 0xff; - zipbufferb[4] = (s >> 24) & 0xff; - zipbufferb[5] = (s >> 16) & 0xff; - zipbufferb[6] = (s >> 8) & 0xff; - zipbufferb[7] = s & 0xff; - } - fseek(zip_drives[id].f, zip_drives[id].base + (i << 9), SEEK_SET); - fwrite(zipbufferb, 1, 512, zip_drives[id].f); - } - break; - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) - hdr_len = 8; - else - hdr_len = 4; - - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { - block_desc_len = zipbufferb[2]; - block_desc_len <<= 8; - block_desc_len |= zipbufferb[3]; - } else { - block_desc_len = zipbufferb[6]; - block_desc_len <<= 8; - block_desc_len |= zipbufferb[7]; - } - } else - block_desc_len = 0; - - pos = hdr_len + block_desc_len; - - while(1) { - page = zipbufferb[pos] & 0x3F; - page_len = zipbufferb[pos + 1]; - - pos += 2; - - if (!(zip_mode_sense_page_flags & (1LL << ((uint64_t) page)))) - error |= 1; - else { - for (i = 0; i < page_len; i++) { - ch = zip_mode_sense_pages_changeable.pages[page][i + 2]; - val = zipbufferb[pos + i]; - old_val = zip_mode_sense_pages_saved[id].pages[page][i + 2]; - if (val != old_val) { - if (ch) - zip_mode_sense_pages_saved[id].pages[page][i + 2] = val; - else - error |= 1; - } - } - } - - pos += page_len; - - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - val = zip_mode_sense_pages_default_scsi.pages[page][0] & 0x80; - else - val = zip_mode_sense_pages_default.pages[page][0] & 0x80; - if (dev->do_page_save && val) - zip_mode_sense_save(id); - - if (pos >= dev->total_length) - break; - } - - if (error) { - zip_invalid_field_pl(id); - return 0; - } - break; - } - - return 1; -} - - -/* This is the general ATAPI PIO request function. */ -static void -zip_pio_request(uint8_t id, uint8_t out) -{ - zip_t *dev = zip[id]; - - int ret = 0; - - if (zip_drives[id].bus_type < ZIP_BUS_SCSI) { - zip_log("ZIP %i: Lowering IDE IRQ\n", id); - ide_irq_lower(ide_drives[zip_drives[id].ide_channel]); - } - - dev->status = BUSY_STAT; - - if (dev->pos >= dev->packet_len) { - zip_log("ZIP %i: %i bytes %s, command done\n", id, dev->pos, out ? "written" : "read"); - - dev->pos = dev->request_pos = 0; - if (out) { - ret = zip_phase_data_out(id); - /* If ret = 0 (phase 1 error), then we do not do anything else other than - free the buffer, as the phase and callback have already been set by the - error function. */ - if (ret) - zip_command_complete(id); - } else - zip_command_complete(id); - zip_buf_free(id); - } else { - zip_log("ZIP %i: %i bytes %s, %i bytes are still left\n", id, dev->pos, - out ? "written" : "read", dev->packet_len - dev->pos); - - /* If less than (packet length) bytes are remaining, update packet length - accordingly. */ - if ((dev->packet_len - dev->pos) < (dev->max_transfer_len)) - dev->max_transfer_len = dev->packet_len - dev->pos; - zip_log("ZIP %i: Packet length %i, request length %i\n", id, dev->packet_len, - dev->max_transfer_len); - - dev->packet_status = out ? ZIP_PHASE_DATA_OUT : ZIP_PHASE_DATA_IN; - - dev->status = BUSY_STAT; - dev->phase = 1; - zip_phase_callback(id); - dev->callback = 0LL; - zip_set_callback(id); - - dev->request_pos = 0; - } -} - - -static int -zip_read_from_ide_dma(uint8_t channel) -{ - zip_t *dev; - - uint8_t id = atapi_zip_drives[channel]; - int ret; - - if (id > ZIP_NUM) - return 0; - - dev = zip[id]; - - if (ide_bus_master_write) { - ret = ide_bus_master_write(channel >> 1, - zipbufferb, dev->packet_len, - ide_bus_master_priv[channel >> 1]); - if (ret == 2) /* DMA not enabled, wait for it to be enabled. */ - return 2; - else if (ret == 1) { /* DMA error. */ - zip_bus_master_error(id); - return 0; - } else - return 1; - } else - return 0; -} - - -static int -zip_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) -{ - zip_t *dev; - - uint8_t id = scsi_zip_drives[scsi_id][scsi_lun]; - int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; - - if (id > ZIP_NUM) - return 0; - - dev = zip[id]; - - zip_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen); - memcpy(zipbufferb, SCSIDevices[scsi_id][scsi_lun].CmdBuffer, *BufLen); - return 1; -} - - -static void -zip_irq_raise(uint8_t id) -{ - if (zip_drives[id].bus_type < ZIP_BUS_SCSI) - ide_irq_raise(ide_drives[zip_drives[id].ide_channel]); -} - - -static int -zip_read_from_dma(uint8_t id) -{ - zip_t *dev = zip[id]; - - int32_t *BufLen = &SCSIDevices[zip_drives[id].scsi_device_id][zip_drives[id].scsi_device_lun].BufferLength; - int ret = 0; - - int in_data_length = 0; - - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - ret = zip_read_from_scsi_dma(zip_drives[id].scsi_device_id, zip_drives[id].scsi_device_lun); - else - ret = zip_read_from_ide_dma(zip_drives[id].ide_channel); - - if (ret != 1) - return ret; - - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { - in_data_length = *BufLen; - zip_log("ZIP %i: SCSI Input data length: %i\n", id, in_data_length); - } else { - in_data_length = dev->max_transfer_len; - zip_log("ZIP %i: ATAPI Input data length: %i\n", id, in_data_length); - } - - ret = zip_phase_data_out(id); - - if (ret) - return 1; - else - return 0; -} - - -static int -zip_write_to_ide_dma(uint8_t channel) -{ - zip_t *dev; - - uint8_t id = atapi_zip_drives[channel]; - int ret; - - if (id > ZIP_NUM) { - zip_log("ZIP %i: Drive not found\n", id); - return 0; - } - - dev = zip[id]; - - if (ide_bus_master_read) { - ret = ide_bus_master_read(channel >> 1, - zipbufferb, dev->packet_len, - ide_bus_master_priv[channel >> 1]); - if (ret == 2) /* DMA not enabled, wait for it to be enabled. */ - return 2; - else if (ret == 1) { /* DMA error. */ - zip_bus_master_error(id); - return 0; - } else - return 1; - } else - return 0; -} - - -static int -zip_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) -{ - zip_t *dev; - - uint8_t id = scsi_zip_drives[scsi_id][scsi_lun]; - int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; - - if (id > ZIP_NUM) - return 0; - - dev = zip[id]; - - zip_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen); - memcpy(SCSIDevices[scsi_id][scsi_lun].CmdBuffer, zipbufferb, *BufLen); - zip_log("ZIP %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, zipbufferb[0], zipbufferb[1], zipbufferb[2], zipbufferb[3], zipbufferb[4], zipbufferb[5], zipbufferb[6], zipbufferb[7]); - zip_log("ZIP %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, SCSIDevices[scsi_id][scsi_lun].CmdBuffer[0], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[1], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[2], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[3], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[4], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[5], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[6], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[7]); - return 1; -} - - -static int -zip_write_to_dma(uint8_t id) -{ - zip_t *dev = zip[id]; - - int32_t *BufLen = &SCSIDevices[zip_drives[id].scsi_device_id][zip_drives[id].scsi_device_lun].BufferLength; - int ret = 0; - - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) { - zip_log("Write to SCSI DMA: (%02X:%02X)\n", zip_drives[id].scsi_device_id, zip_drives[id].scsi_device_lun); - ret = zip_write_to_scsi_dma(zip_drives[id].scsi_device_id, zip_drives[id].scsi_device_lun); - } else - ret = zip_write_to_ide_dma(zip_drives[id].ide_channel); - - if (zip_drives[id].bus_type == ZIP_BUS_SCSI) - zip_log("ZIP %i: SCSI Output data length: %i\n", id, *BufLen); - else - zip_log("ZIP %i: ATAPI Output data length: %i\n", id, dev->packet_len); - - return ret; -} - - -/* If the result is 1, issue an IRQ, otherwise not. */ -void -zip_phase_callback(uint8_t id) -{ - zip_t *dev = zip[id]; - int ret; - - switch(dev->packet_status) { - case ZIP_PHASE_IDLE: - zip_log("ZIP %i: ZIP_PHASE_IDLE\n", id); - dev->pos=0; - dev->phase = 1; - dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); - return; - case ZIP_PHASE_COMMAND: - zip_log("ZIP %i: ZIP_PHASE_COMMAND\n", id); - dev->status = BUSY_STAT | (dev->status &ERR_STAT); - memcpy(dev->atapi_cdb, zipbufferb, dev->cdb_len); - zip_command(id, dev->atapi_cdb); - return; - case ZIP_PHASE_COMPLETE: - zip_log("ZIP %i: ZIP_PHASE_COMPLETE\n", id); - dev->status = READY_STAT; - dev->phase = 3; - dev->packet_status = 0xFF; - ui_sb_update_icon(SB_ZIP | id, 0); - zip_irq_raise(id); - return; - case ZIP_PHASE_DATA_OUT: - zip_log("ZIP %i: ZIP_PHASE_DATA_OUT\n", id); - dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); - dev->phase = 0; - zip_irq_raise(id); - return; - case ZIP_PHASE_DATA_OUT_DMA: - zip_log("ZIP %i: ZIP_PHASE_DATA_OUT_DMA\n", id); - ret = zip_read_from_dma(id); - - if ((ret == 1) || (zip_drives[id].bus_type == ZIP_BUS_SCSI)) { - zip_log("ZIP %i: DMA data out phase done\n"); - zip_buf_free(id); - zip_command_complete(id); - } else if (ret == 2) { - zip_log("ZIP %i: DMA out not enabled, wait\n"); - zip_command_bus(id); - } else { - zip_log("ZIP %i: DMA data out phase failure\n"); - zip_buf_free(id); - } - return; - case ZIP_PHASE_DATA_IN: - zip_log("ZIP %i: ZIP_PHASE_DATA_IN\n", id); - dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); - dev->phase = 2; - zip_irq_raise(id); - return; - case ZIP_PHASE_DATA_IN_DMA: - zip_log("ZIP %i: ZIP_PHASE_DATA_IN_DMA\n", id); - ret = zip_write_to_dma(id); - - if ((ret == 1) || (zip_drives[id].bus_type == ZIP_BUS_SCSI)) { - zip_log("ZIP %i: DMA data in phase done\n"); - zip_buf_free(id); - zip_command_complete(id); - } else if (ret == 2) { - zip_log("ZIP %i: DMA in not enabled, wait\n"); - zip_command_bus(id); - } else { - zip_log("ZIP %i: DMA data in phase failure\n"); - zip_buf_free(id); - } - return; - case ZIP_PHASE_ERROR: - zip_log("ZIP %i: ZIP_PHASE_ERROR\n", id); - dev->status = READY_STAT | ERR_STAT; - dev->phase = 3; - dev->packet_status = 0xFF; - zip_irq_raise(id); - ui_sb_update_icon(SB_ZIP | id, 0); - return; - } -} - - -uint32_t -zip_read(uint8_t channel, int length) -{ - zip_t *dev; - - uint16_t *zipbufferw; - uint32_t *zipbufferl; - - uint8_t id = atapi_zip_drives[channel]; - - uint32_t temp = 0; - - if (id > ZIP_NUM) - return 0; - - dev = zip[id]; - - zipbufferw = (uint16_t *) zipbufferb; - zipbufferl = (uint32_t *) zipbufferb; - - if (!zipbufferb) - return 0; - - /* Make sure we return a 0 and don't attempt to read from the buffer if we're transferring bytes beyond it, - which can happen when issuing media access commands with an allocated length below minimum request length - (which is 1 sector = 512 bytes). */ - switch(length) { - case 1: - temp = (dev->pos < dev->packet_len) ? zipbufferb[dev->pos] : 0; - dev->pos++; - dev->request_pos++; - break; - case 2: - temp = (dev->pos < dev->packet_len) ? zipbufferw[dev->pos >> 1] : 0; - dev->pos += 2; - dev->request_pos += 2; - break; - case 4: - temp = (dev->pos < dev->packet_len) ? zipbufferl[dev->pos >> 2] : 0; - dev->pos += 4; - dev->request_pos += 4; - break; - default: - return 0; - } - - if (dev->packet_status == ZIP_PHASE_DATA_IN) { - zip_log("ZIP %i: Returning: %04X (buffer position: %05i, request position: %05i)\n", - id, temp, (dev->pos - 2) & 0xffff, (dev->request_pos - 2) & 0xffff); - if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { - /* Time for a DRQ. */ - zip_log("ZIP %i: Issuing read callback\n", id); - zip_pio_request(id, 0); - } - return temp; - } else { - zip_log("ZIP %i: Returning: 0000 (buffer position: %05i, request position: %05i)\n", - id, (dev->pos - 2) & 0xffff, (dev->request_pos - 2) & 0xffff); - return 0; - } -} - - -void -zip_write(uint8_t channel, uint32_t val, int length) -{ - zip_t *dev; - - uint16_t *zipbufferw; - uint32_t *zipbufferl; - - uint8_t id = atapi_zip_drives[channel]; - - if (id > ZIP_NUM) - return; - - dev = zip[id]; - - if (dev->packet_status == ZIP_PHASE_IDLE) { - if (!zipbufferb) - zip_buf_alloc(id, dev->cdb_len); - } - - zipbufferw = (uint16_t *) zipbufferb; - zipbufferl = (uint32_t *) zipbufferb; - - if (!zipbufferb) - return; - - switch(length) { - case 1: - zipbufferb[dev->pos] = val & 0xff; - dev->pos++; - dev->request_pos++; - break; - case 2: - zipbufferw[dev->pos >> 1] = val & 0xffff; - dev->pos += 2; - dev->request_pos += 2; - break; - case 4: - zipbufferl[dev->pos >> 2] = val; - dev->pos += 4; - dev->request_pos += 4; - break; - default: - return; - } - - if (dev->packet_status == ZIP_PHASE_DATA_OUT) { - if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { - /* Time for a DRQ. */ - zip_pio_request(id, 1); - } - return; - } else if (dev->packet_status == ZIP_PHASE_IDLE) { - if (dev->pos >= dev->cdb_len) { - dev->pos=0; - dev->status = BUSY_STAT; - dev->packet_status = ZIP_PHASE_COMMAND; - timer_process(); - zip_phase_callback(id); - timer_update_outstanding(); - } - return; - } -} - - -/* Peform a master init on the entire module. */ -void -zip_global_init(void) -{ - /* Clear the global data. */ - memset(zip, 0x00, sizeof(zip)); - memset(zip_drives, 0x00, sizeof(zip_drives)); -} - - -void -zip_hard_reset(void) -{ - int c; - - zip_destroy_drives(); - - for (c=0; c - * - * Copyright 2018 Miran Grca. - */ -#ifndef EMU_ZIP_H -#define EMU_ZIP_H - - -#define ZIP_NUM 4 - -#define ZIP_PHASE_IDLE 0x00 -#define ZIP_PHASE_COMMAND 0x01 -#define ZIP_PHASE_COMPLETE 0x02 -#define ZIP_PHASE_DATA_IN 0x03 -#define ZIP_PHASE_DATA_IN_DMA 0x04 -#define ZIP_PHASE_DATA_OUT 0x05 -#define ZIP_PHASE_DATA_OUT_DMA 0x06 -#define ZIP_PHASE_ERROR 0x80 - -#define BUF_SIZE 32768 - -#define ZIP_TIME (5LL * 100LL * (1LL << TIMER_SHIFT)) - -#define ZIP_SECTORS (96*2048) - -#define ZIP_250_SECTORS (489532) - - -enum { - ZIP_BUS_DISABLED = 0, - ZIP_BUS_ATAPI = 4, - ZIP_BUS_SCSI, - ZIP_BUS_USB -}; - - -typedef struct { - uint8_t previous_command, error, - features, status, - phase, *buffer, - atapi_cdb[16], - current_cdb[16], - sense[256]; - - uint16_t request_length, max_transfer_len; - - int toctimes, media_status, - is_dma, requested_blocks, - current_page_len, current_page_pos, - total_length, written_length, - mode_select_phase, do_page_save, - callback, data_pos, - packet_status, unit_attention, - cdb_len_setting, cdb_len, - request_pos, total_read, - block_total, all_blocks_total, - old_len, block_descriptor_len, - init_length; - - uint32_t sector_pos, sector_len, - packet_len, pos, - seek_pos; - - uint64_t current_page_code; -} zip_t; - -typedef struct { - unsigned int bus_type; /* 0 = ATAPI, 1 = SCSI */ - uint8_t ide_channel, - bus_mode; /* Bit 0 = PIO suported; - Bit 1 = DMA supportd. */ - - unsigned int scsi_device_id, scsi_device_lun, - is_250; - - wchar_t image_path[1024], - prev_image_path[1024]; - - int read_only, ui_writeprot; - - uint32_t medium_size, base; - - FILE *f; -} zip_drive_t; - - -extern zip_t *zip[ZIP_NUM]; -extern zip_drive_t zip_drives[ZIP_NUM]; -extern uint8_t atapi_zip_drives[8]; -extern uint8_t scsi_zip_drives[16][8]; - -#define zip_sense_error zip[id]->sense[0] -#define zip_sense_key zip[id]->sense[2] -#define zip_asc zip[id]->sense[12] -#define zip_ascq zip[id]->sense[13] - - -#ifdef __cplusplus -extern "C" { -#endif - -extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv); -extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv); -extern void (*ide_bus_master_set_irq)(int channel, void *priv); -extern void *ide_bus_master_priv[2]; -extern void ioctl_close(uint8_t id); - -extern uint32_t zip_mode_sense_get_channel(uint8_t id, int channel); -extern uint32_t zip_mode_sense_get_volume(uint8_t id, int channel); -extern void build_atapi_zip_map(void); -extern void build_scsi_zip_map(void); -extern int zip_ZIP_PHASE_to_scsi(uint8_t id); -extern int zip_atapi_phase_to_scsi(uint8_t id); -extern void zip_command(uint8_t id, uint8_t *cdb); -extern void zip_phase_callback(uint8_t id); -extern uint32_t zip_read(uint8_t channel, int length); -extern void zip_write(uint8_t channel, uint32_t val, int length); - -extern void zip_close(uint8_t id); -extern void zip_disk_reload(uint8_t id); -extern void zip_reset(uint8_t id); -extern void zip_set_signature(int id); -extern void zip_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length); -extern void zip_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); -extern void zip_insert(uint8_t id); - -extern int find_zip_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); -extern int zip_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len); - -extern void zip_global_init(void); -extern void zip_hard_reset(void); - -extern int zip_load(uint8_t id, wchar_t *fn); - -extern void zip_destroy_drives(void); -extern void zip_close(uint8_t id); - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_ZIP_H*/ diff --git a/backup code/dma.c.old b/backup code/dma.c.old deleted file mode 100644 index bbc591349..000000000 --- a/backup code/dma.c.old +++ /dev/null @@ -1,853 +0,0 @@ -/* - * 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 Intel DMA controllers. - * - * Version: @(#)dma.c 1.0.9 2018/03/28 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "86box.h" -#include "cpu/cpu.h" -#include "cpu/x86.h" -#include "machine/machine.h" -#include "mca.h" -#include "mem.h" -#include "io.h" -#include "dma.h" - - -static uint8_t dmaregs[16]; -static uint8_t dma16regs[16]; -static uint8_t dmapages[16]; - -dma_t dma[8]; - -static int dma_wp, dma16_wp; -static uint8_t dma_m; -static uint8_t dma_stat; -static uint8_t dma_stat_rq; -static uint8_t dma_command, dma16_command; - -static struct -{ - int xfr_command, xfr_channel; - int byte_ptr; - - int is_ps2; -} dma_ps2; - -#define DMA_PS2_IOA (1 << 0) -#define DMA_PS2_XFER_MEM_TO_IO (1 << 2) -#define DMA_PS2_XFER_IO_TO_MEM (3 << 2) -#define DMA_PS2_XFER_MASK (3 << 2) -#define DMA_PS2_DEC2 (1 << 4) -#define DMA_PS2_SIZE16 (1 << 6) - -static void dma_ps2_run(int channel); - -void dma_reset(void) -{ - int c; - - dma_wp = dma16_wp = 0; - dma_m = 0; - - for (c = 0; c < 16; c++) - dmaregs[c] = 0; - for (c = 0; c < 8; c++) - { - dma[c].mode = 0; - dma[c].ac = 0; - dma[c].cc = 0; - dma[c].ab = 0; - dma[c].cb = 0; - dma[c].size = (c & 4) ? 1 : 0; - } -} - -uint8_t dma_read(uint16_t addr, void *priv) -{ - int channel = (addr >> 1) & 3; - uint8_t temp; - switch (addr & 0xf) - { - case 0: case 2: case 4: case 6: /*Address registers*/ - dma_wp ^= 1; - if (dma_wp) - return dma[channel].ac & 0xff; - return (dma[channel].ac >> 8) & 0xff; - - case 1: case 3: case 5: case 7: /*Count registers*/ - dma_wp ^= 1; - if (dma_wp) - temp = dma[channel].cc & 0xff; - else - temp = dma[channel].cc >> 8; - return temp; - - case 8: /*Status register*/ - temp = dma_stat & 0xf; - dma_stat &= ~0xf; - return temp; - - case 0xd: - return 0; - } - return dmaregs[addr & 0xf]; -} - -void dma_write(uint16_t addr, uint8_t val, void *priv) -{ - int channel = (addr >> 1) & 3; - dmaregs[addr & 0xf] = val; - switch (addr & 0xf) - { - case 0: case 2: case 4: case 6: /*Address registers*/ - dma_wp ^= 1; - if (dma_wp) - dma[channel].ab = (dma[channel].ab & 0xffff00) | val; - else - dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8); - dma[channel].ac = dma[channel].ab; - return; - - case 1: case 3: case 5: case 7: /*Count registers*/ - dma_wp ^= 1; - if (dma_wp) - dma[channel].cb = (dma[channel].cb & 0xff00) | val; - else - dma[channel].cb = (dma[channel].cb & 0x00ff) | (val << 8); - dma[channel].cc = dma[channel].cb; - return; - - case 8: /*Control register*/ - dma_command = val; - return; - - case 0xa: /*Mask*/ - if (val & 4) - dma_m |= (1 << (val & 3)); - else - dma_m &= ~(1 << (val & 3)); - return; - - case 0xb: /*Mode*/ - channel = (val & 3); - dma[channel].mode = val; - if (dma_ps2.is_ps2) - { - dma[channel].ps2_mode &= ~0x1c; - if (val & 0x20) - dma[channel].ps2_mode |= 0x10; - if ((val & 0xc) == 8) - dma[channel].ps2_mode |= 4; - else if ((val & 0xc) == 4) - dma[channel].ps2_mode |= 0xc; - } - return; - - case 0xc: /*Clear FF*/ - dma_wp = 0; - return; - - case 0xd: /*Master clear*/ - dma_wp = 0; - dma_m |= 0xf; - return; - - case 0xf: /*Mask write*/ - dma_m = (dma_m & 0xf0) | (val & 0xf); - return; - } -} - -static uint8_t dma_ps2_read(uint16_t addr, void *priv) -{ - dma_t *dma_c = &dma[dma_ps2.xfr_channel]; - uint8_t temp = 0xff; - - switch (addr) - { - case 0x1a: - switch (dma_ps2.xfr_command) - { - case 2: /*Address*/ - case 3: - switch (dma_ps2.byte_ptr) - { - case 0: - temp = dma_c->ac & 0xff; - dma_ps2.byte_ptr = 1; - break; - case 1: - temp = (dma_c->ac >> 8) & 0xff; - dma_ps2.byte_ptr = 2; - break; - case 2: - temp = (dma_c->ac >> 16) & 0xff; - dma_ps2.byte_ptr = 0; - break; - } - break; - case 4: /*Count*/ - case 5: - if (dma_ps2.byte_ptr) - temp = dma_c->cc >> 8; - else - temp = dma_c->cc & 0xff; - dma_ps2.byte_ptr = (dma_ps2.byte_ptr + 1) & 1; - break; - case 6: /*Read DMA status*/ - if (dma_ps2.byte_ptr) - { - temp = ((dma_stat_rq & 0xf0) >> 4) | (dma_stat & 0xf0); - dma_stat &= ~0xf0; - dma_stat_rq &= ~0xf0; - } - else - { - temp = (dma_stat_rq & 0xf) | ((dma_stat & 0xf) << 4); - dma_stat &= ~0xf; - dma_stat_rq &= ~0xf; - } - dma_ps2.byte_ptr = (dma_ps2.byte_ptr + 1) & 1; - break; - case 7: /*Mode*/ - temp = dma_c->ps2_mode; - break; - case 8: /*Arbitration Level*/ - temp = dma_c->arb_level; - break; - - default: - fatal("Bad XFR Read command %i channel %i\n", dma_ps2.xfr_command, dma_ps2.xfr_channel); - } - break; - } - - return temp; -} - -static void dma_ps2_write(uint16_t addr, uint8_t val, void *priv) -{ - dma_t *dma_c = &dma[dma_ps2.xfr_channel]; - uint8_t mode; - - switch (addr) - { - case 0x18: - dma_ps2.xfr_channel = val & 0x7; - dma_ps2.xfr_command = val >> 4; - dma_ps2.byte_ptr = 0; - switch (dma_ps2.xfr_command) - { - case 9: /*Set DMA mask*/ - dma_m |= (1 << dma_ps2.xfr_channel); - break; - case 0xa: /*Reset DMA mask*/ - dma_m &= ~(1 << dma_ps2.xfr_channel); - break; - case 0xb: - if (!(dma_m & (1 << dma_ps2.xfr_channel))) - dma_ps2_run(dma_ps2.xfr_channel); - break; - } - break; - case 0x1a: - switch (dma_ps2.xfr_command) - { - case 0: /*I/O address*/ - if (dma_ps2.byte_ptr) - dma_c->io_addr = (dma_c->io_addr & 0x00ff) | (val << 8); - else - dma_c->io_addr = (dma_c->io_addr & 0xff00) | val; - dma_ps2.byte_ptr = (dma_ps2.byte_ptr + 1) & 1; - break; - - case 2: /*Address*/ - switch (dma_ps2.byte_ptr) - { - case 0: - dma_c->ac = (dma_c->ac & 0xffff00) | val; - dma_ps2.byte_ptr = 1; - break; - case 1: - dma_c->ac = (dma_c->ac & 0xff00ff) | (val << 8); - dma_ps2.byte_ptr = 2; - break; - case 2: - dma_c->ac = (dma_c->ac & 0x00ffff) | (val << 16); - dma_ps2.byte_ptr = 0; - break; - } - dma_c->ab = dma_c->ac; - break; - - case 4: /*Count*/ - if (dma_ps2.byte_ptr) - dma_c->cc = (dma_c->cc & 0xff) | (val << 8); - else - dma_c->cc = (dma_c->cc & 0xff00) | val; - dma_ps2.byte_ptr = (dma_ps2.byte_ptr + 1) & 1; - dma_c->cb = dma_c->cc; - break; - - case 7: /*Mode register*/ - mode = 0; - if (val & DMA_PS2_DEC2) - mode |= 0x20; - if ((val & DMA_PS2_XFER_MASK) == DMA_PS2_XFER_MEM_TO_IO) - mode |= 8; - else if ((val & DMA_PS2_XFER_MASK) == DMA_PS2_XFER_IO_TO_MEM) - mode |= 4; - dma_c->mode = (dma_c->mode & ~0x2c) | mode; - dma_c->ps2_mode = val; - dma_c->size = val & DMA_PS2_SIZE16; - break; - - case 8: /*Arbitration Level*/ - dma_c->arb_level = val; - break; - - default: - fatal("Bad XFR command %i channel %i val %02x\n", dma_ps2.xfr_command, dma_ps2.xfr_channel, val); - } - break; - } -} - -uint8_t dma16_read(uint16_t addr, void *priv) -{ - int channel = ((addr >> 2) & 3) + 4; - uint8_t temp; - addr >>= 1; - switch (addr & 0xf) - { - case 0: case 2: case 4: case 6: /*Address registers*/ - dma16_wp ^= 1; - if (dma_ps2.is_ps2) - { - if (dma16_wp) - return dma[channel].ac; - return (dma[channel].ac >> 8) & 0xff; - } - if (dma16_wp) - return (dma[channel].ac >> 1) & 0xff; - return (dma[channel].ac >> 9) & 0xff; - - case 1: case 3: case 5: case 7: /*Count registers*/ - dma16_wp ^= 1; - if (dma16_wp) - temp = dma[channel].cc & 0xff; - else - temp = dma[channel].cc >> 8; - return temp; - - case 8: /*Status register*/ - temp = dma_stat >> 4; - dma_stat &= ~0xf0; - return temp; - } - return dma16regs[addr & 0xf]; -} - -void dma16_write(uint16_t addr, uint8_t val, void *priv) -{ - int channel = ((addr >> 2) & 3) + 4; - addr >>= 1; - dma16regs[addr & 0xf] = val; - switch (addr & 0xf) - { - case 0: case 2: case 4: case 6: /*Address registers*/ - dma16_wp ^= 1; - if (dma_ps2.is_ps2) - { - if (dma16_wp) - dma[channel].ab = (dma[channel].ab & 0xffff00) | val; - else - dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8); - } - else - { - if (dma16_wp) - dma[channel].ab = (dma[channel].ab & 0xfffe00) | (val << 1); - else - dma[channel].ab = (dma[channel].ab & 0xfe01ff) | (val << 9); - } - dma[channel].ac = dma[channel].ab; - return; - - case 1: case 3: case 5: case 7: /*Count registers*/ - dma16_wp ^= 1; - if (dma16_wp) - dma[channel].cb = (dma[channel].cb & 0xff00) | val; - else - dma[channel].cb = (dma[channel].cb & 0x00ff) | (val << 8); - dma[channel].cc = dma[channel].cb; - return; - - case 8: /*Control register*/ - return; - - case 0xa: /*Mask*/ - if (val & 4) - dma_m |= (0x10 << (val & 3)); - else - dma_m &= ~(0x10 << (val & 3)); - return; - - case 0xb: /*Mode*/ - channel = (val & 3) + 4; - dma[channel].mode = val; - if (dma_ps2.is_ps2) - { - dma[channel].ps2_mode &= ~0x1c; - if (val & 0x20) - dma[channel].ps2_mode |= 0x10; - if ((val & 0xc) == 8) - dma[channel].ps2_mode |= 4; - else if ((val & 0xc) == 4) - dma[channel].ps2_mode |= 0xc; - } - return; - - case 0xc: /*Clear FF*/ - dma16_wp = 0; - return; - - case 0xd: /*Master clear*/ - dma16_wp = 0; - dma_m |= 0xf0; - return; - - case 0xf: /*Mask write*/ - dma_m = (dma_m & 0x0f) | ((val & 0xf) << 4); - return; - } -} - - -void dma_page_write(uint16_t addr, uint8_t val, void *priv) -{ - dmapages[addr & 0xf] = val; - switch (addr & 0xf) - { - case 1: - dma[2].page = (AT) ? val : val & 0xf; - dma[2].ab = (dma[2].ab & 0xffff) | (dma[2].page << 16); - dma[2].ac = (dma[2].ac & 0xffff) | (dma[2].page << 16); - break; - case 2: - dma[3].page = (AT) ? val : val & 0xf; - dma[3].ab = (dma[3].ab & 0xffff) | (dma[3].page << 16); - dma[3].ac = (dma[3].ac & 0xffff) | (dma[3].page << 16); - break; - case 3: - dma[1].page = (AT) ? val : val & 0xf; - dma[1].ab = (dma[1].ab & 0xffff) | (dma[1].page << 16); - dma[1].ac = (dma[1].ac & 0xffff) | (dma[1].page << 16); - break; - case 7: - dma[0].page = (AT) ? val : val & 0xf; - dma[0].ab = (dma[0].ab & 0xffff) | (dma[0].page << 16); - dma[0].ac = (dma[0].ac & 0xffff) | (dma[0].page << 16); - break; - case 0x9: - dma[6].page = val & 0xfe; - dma[6].ab = (dma[6].ab & 0x1ffff) | (dma[6].page << 16); - dma[6].ac = (dma[6].ac & 0x1ffff) | (dma[6].page << 16); - break; - case 0xa: - dma[7].page = val & 0xfe; - dma[7].ab = (dma[7].ab & 0x1ffff) | (dma[7].page << 16); - dma[7].ac = (dma[7].ac & 0x1ffff) | (dma[7].page << 16); - break; - case 0xb: - dma[5].page = val & 0xfe; - dma[5].ab = (dma[5].ab & 0x1ffff) | (dma[5].page << 16); - dma[5].ac = (dma[5].ac & 0x1ffff) | (dma[5].page << 16); - break; - case 0xf: - dma[4].page = val & 0xfe; - dma[4].ab = (dma[4].ab & 0x1ffff) | (dma[4].page << 16); - dma[4].ac = (dma[4].ac & 0x1ffff) | (dma[4].page << 16); - break; - } -} - -uint8_t dma_page_read(uint16_t addr, void *priv) -{ - return dmapages[addr & 0xf]; -} - -void dma_init(void) -{ - io_sethandler(0x0000, 0x0010, dma_read, NULL, NULL, dma_write, NULL, NULL, NULL); - io_sethandler(0x0080, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); - dma_ps2.is_ps2 = 0; -} - -void dma16_init(void) -{ - io_sethandler(0x00C0, 0x0020, dma16_read, NULL, NULL, dma16_write, NULL, NULL, NULL); - io_sethandler(0x0088, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); -} - -void dma_alias_set(void) -{ - io_sethandler(0x0090, 0x0010, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); -} - -void dma_alias_remove(void) -{ - io_removehandler(0x0090, 0x0010, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); -} - -void dma_alias_remove_piix(void) -{ - io_removehandler(0x0090, 0x0001, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); - io_removehandler(0x0094, 0x0003, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); - io_removehandler(0x0098, 0x0001, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); - io_removehandler(0x009C, 0x0003, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); -} - -void ps2_dma_init(void) -{ - io_sethandler(0x0018, 0x0001, dma_ps2_read, NULL, NULL, dma_ps2_write, NULL, NULL, NULL); - io_sethandler(0x001a, 0x0001, dma_ps2_read, NULL, NULL, dma_ps2_write, NULL, NULL, NULL); - dma_ps2.is_ps2 = 1; -} - - -uint8_t _dma_read(uint32_t addr) -{ - uint8_t temp = mem_readb_phys_dma(addr); - return temp; -} - -void _dma_write(uint32_t addr, uint8_t val) -{ - mem_writeb_phys_dma(addr, val); - mem_invalidate_range(addr, addr); -} - -int dma_channel_read(int channel) -{ - dma_t *dma_c = &dma[channel]; - uint16_t temp; - int tc = 0; - - if (channel < 4) - { - if (dma_command & 0x04) - return DMA_NODATA; - } - else - { - if (dma16_command & 0x04) - return DMA_NODATA; - } - - if (!AT) - refreshread(); - - if (dma_m & (1 << channel)) - return DMA_NODATA; - if ((dma_c->mode & 0xC) != 8) - return DMA_NODATA; - - if (!dma_c->size) - { - temp = _dma_read(dma_c->ac); - - if (dma_c->mode & 0x20) - { - if (dma_ps2.is_ps2) - dma_c->ac--; - else - dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff); - } - else - { - if (dma_ps2.is_ps2) - dma_c->ac++; - else - dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff); - } - } - else - { - temp = _dma_read(dma_c->ac) | - (_dma_read(dma_c->ac + 1) << 8); - - if (dma_c->mode & 0x20) - { - if (dma_ps2.is_ps2) - dma_c->ac -= 2; - else - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff); - } - else - { - if (dma_ps2.is_ps2) - dma_c->ac += 2; - else - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff); - } - } - - dma_stat_rq |= (1 << channel); - - dma_c->cc--; - if (dma_c->cc < 0) - { - tc = 1; - if (dma_c->mode & 0x10) /*Auto-init*/ - { - dma_c->cc = dma_c->cb; - dma_c->ac = dma_c->ab; - } - else - dma_m |= (1 << channel); - dma_stat |= (1 << channel); - } - - if (tc) - return temp | DMA_OVER; - return temp; -} - -int dma_channel_write(int channel, uint16_t val) -{ - dma_t *dma_c = &dma[channel]; - - if (channel < 4) - { - if (dma_command & 0x04) - return DMA_NODATA; - } - else - { - if (dma16_command & 0x04) - return DMA_NODATA; - } - - if (!AT) - refreshread(); - - if (dma_m & (1 << channel)) - return DMA_NODATA; - if ((dma_c->mode & 0xC) != 4) - return DMA_NODATA; - - if (!dma_c->size) - { - _dma_write(dma_c->ac, val); - - if (dma_c->mode & 0x20) - { - if (dma_ps2.is_ps2) - dma_c->ac--; - else - dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff); - } - else - { - if (dma_ps2.is_ps2) - dma_c->ac++; - else - dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff); - } - } - else - { - _dma_write(dma_c->ac, val); - _dma_write(dma_c->ac + 1, val >> 8); - - if (dma_c->mode & 0x20) - { - if (dma_ps2.is_ps2) - dma_c->ac -= 2; - else - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff); - } - else - { - if (dma_ps2.is_ps2) - dma_c->ac += 2; - else - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff); - } - } - - dma_stat_rq |= (1 << channel); - - dma_c->cc--; - if (dma_c->cc < 0) - { - if (dma_c->mode & 0x10) /*Auto-init*/ - { - dma_c->cc = dma_c->cb; - dma_c->ac = dma_c->ab; - } - else - dma_m |= (1 << channel); - dma_stat |= (1 << channel); - } - - if (dma_m & (1 << channel)) - return DMA_OVER; - - return 0; -} - -static void dma_ps2_run(int channel) -{ - dma_t *dma_c = &dma[channel]; - - switch (dma_c->ps2_mode & DMA_PS2_XFER_MASK) - { - case DMA_PS2_XFER_MEM_TO_IO: - do - { - if (!dma_c->size) - { - uint8_t temp = _dma_read(dma_c->ac); - outb(dma_c->io_addr, temp); - - if (dma_c->ps2_mode & DMA_PS2_DEC2) - dma_c->ac--; - else - dma_c->ac++; - } - else - { - uint16_t temp = _dma_read(dma_c->ac) | (_dma_read(dma_c->ac + 1) << 8); - outw(dma_c->io_addr, temp); - - if (dma_c->ps2_mode & DMA_PS2_DEC2) - dma_c->ac -= 2; - else - dma_c->ac += 2; - } - - dma_stat_rq |= (1 << channel); - dma_c->cc--; - } while (dma_c->cc > 0); - - dma_stat |= (1 << channel); - break; - - case DMA_PS2_XFER_IO_TO_MEM: - do - { - if (!dma_c->size) - { - uint8_t temp = inb(dma_c->io_addr); - _dma_write(dma_c->ac, temp); - - if (dma_c->ps2_mode & DMA_PS2_DEC2) - dma_c->ac--; - else - dma_c->ac++; - } - else - { - uint16_t temp = inw(dma_c->io_addr); - _dma_write(dma_c->ac, temp & 0xff); - _dma_write(dma_c->ac + 1, temp >> 8); - - if (dma_c->ps2_mode & DMA_PS2_DEC2) - dma_c->ac -= 2; - else - dma_c->ac += 2; - } - - dma_stat_rq |= (1 << channel); - dma_c->cc--; - } while (dma_c->cc > 0); - - ps2_cache_clean(); - dma_stat |= (1 << channel); - break; - - default: /*Memory verify*/ - do - { - if (!dma_c->size) - { - if (dma_c->ps2_mode & DMA_PS2_DEC2) - dma_c->ac--; - else - dma_c->ac++; - } - else - { - if (dma_c->ps2_mode & DMA_PS2_DEC2) - dma_c->ac -= 2; - else - dma_c->ac += 2; - } - - dma_stat_rq |= (1 << channel); - dma->cc--; - } while (dma->cc > 0); - - dma_stat |= (1 << channel); - break; - } -} - -int dma_mode(int channel) -{ - if (channel < 4) - { - return dma[channel].mode; - } - else - { - return dma[channel & 3].mode; - } -} - -/* DMA Bus Master Page Read/Write */ -void DMAPageRead(uint32_t PhysAddress, uint8_t *DataRead, uint32_t TotalSize) -{ - uint32_t i = 0; - -#if 0 - memcpy(DataRead, &ram[PhysAddress], TotalSize); -#else - for (i = 0; i < TotalSize; i++) - DataRead[i] = mem_readb_phys_dma(PhysAddress + i); -#endif -} - -void DMAPageWrite(uint32_t PhysAddress, const uint8_t *DataWrite, uint32_t TotalSize) -{ - uint32_t i = 0; - -#if 0 - mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1); - memcpy(&ram[PhysAddress], DataWrite, TotalSize); -#else - for (i = 0; i < TotalSize; i++) - mem_writeb_phys_dma(PhysAddress + i, DataWrite[i]); - - mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1); -#endif -} diff --git a/backup code/dma.h.old b/backup code/dma.h.old deleted file mode 100644 index 223994a17..000000000 --- a/backup code/dma.h.old +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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 Intel DMA controllers. - * - * Version: @(#)dma.h 1.0.5 2018/03/11 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - */ -#ifndef EMU_DMA_H -# define EMU_DMA_H - - -#define DMA_NODATA -1 -#define DMA_OVER 0x10000 -#define DMA_VERIFY 0x20000 - - -/*DMA*/ -typedef struct dma_t -{ - uint32_t ab, ac; - uint16_t cb; - int cc; - int wp; - uint8_t m, mode; - uint8_t page; - uint8_t stat, stat_rq; - uint8_t command; - int size; - - uint8_t ps2_mode; - uint8_t arb_level; - uint16_t io_addr; -} dma_t; - -extern dma_t dma[8]; - -extern void dma_init(void); -extern void dma16_init(void); -extern void ps2_dma_init(void); -extern void dma_reset(void); -extern int dma_mode(int channel); - -extern void readdma0(void); -extern int readdma1(void); -extern uint8_t readdma2(void); -extern int readdma3(void); - -extern void writedma2(uint8_t temp); - -extern int dma_channel_read(int channel); -extern int dma_channel_write(int channel, uint16_t val); - -extern void dma_alias_set(void); -extern void dma_alias_remove(void); -extern void dma_alias_remove_piix(void); - -extern void DMAPageRead(uint32_t PhysAddress, uint8_t *DataRead, - uint32_t TotalSize); -extern void DMAPageWrite(uint32_t PhysAddress, const uint8_t *DataWrite, - uint32_t TotalSize); - - -#endif /*EMU_DMA_H*/ diff --git a/backup code/intel_piix - Cópia.c b/backup code/intel_piix - Cópia.c deleted file mode 100644 index c2246abb3..000000000 --- a/backup code/intel_piix - Cópia.c +++ /dev/null @@ -1,916 +0,0 @@ -/* - * 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. - * - * Emulation of the Intel PIIX and PIIX3 Xcelerators. - * - * PRD format : - * word 0 - base address - * word 1 - bits 1-15 = byte count, bit 31 = end of transfer - * - * Version: @(#)intel_piix.c 1.0.16 2018/05/11 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "scsi/scsi.h" -#include "cdrom/cdrom.h" -#include "dma.h" -#include "io.h" -#include "device.h" -#include "keyboard.h" -#include "mem.h" -#include "pci.h" -#include "pic.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "disk/zip.h" -#include "piix.h" - - -typedef struct -{ - uint8_t command, status, - ptr0; - uint32_t ptr, ptr_cur, - addr; - int count, eot; -} piix_busmaster_t; - -typedef struct -{ - int type; - uint8_t regs[256], regs_ide[256]; - piix_busmaster_t bm[2]; -} piix_t; - - -static uint8_t piix_bus_master_read(uint16_t port, void *priv); -static uint16_t piix_bus_master_readw(uint16_t port, void *priv); -static uint32_t piix_bus_master_readl(uint16_t port, void *priv); -static void piix_bus_master_write(uint16_t port, uint8_t val, void *priv); -static void piix_bus_master_writew(uint16_t port, uint16_t val, void *priv); -static void piix_bus_master_writel(uint16_t port, uint32_t val, void *priv); - - -#ifdef ENABLE_PIIX_LOG -int piix_do_log = ENABLE_PIIX_LOG; -#endif - - -static void -piix_log(const char *format, ...) -{ -#ifdef ENABLE_PIIX_LOG - va_list ap; - - if (piix_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -static void -piix_bus_master_handlers(piix_t *dev, uint16_t old_base) -{ - uint16_t base; - - base = (dev->regs_ide[0x20] & 0xf0) | (dev->regs_ide[0x21] << 8); - io_removehandler(old_base, 0x08, - piix_bus_master_read, piix_bus_master_readw, piix_bus_master_readl, - piix_bus_master_write, piix_bus_master_writew, piix_bus_master_writel, - &dev->bm[0]); - io_removehandler(old_base + 8, 0x08, - piix_bus_master_read, piix_bus_master_readw, piix_bus_master_readl, - piix_bus_master_write, piix_bus_master_writew, piix_bus_master_writel, - &dev->bm[1]); - - if ((dev->regs_ide[0x04] & 1) && base) { - io_sethandler(base, 0x08, - piix_bus_master_read, piix_bus_master_readw, piix_bus_master_readl, - piix_bus_master_write, piix_bus_master_writew, piix_bus_master_writel, - &dev->bm[0]); - io_sethandler(base + 8, 0x08, - piix_bus_master_read, piix_bus_master_readw, piix_bus_master_readl, - piix_bus_master_write, piix_bus_master_writew, piix_bus_master_writel, - &dev->bm[1]); - } -} - - -static void -piix_write(int func, int addr, uint8_t val, void *priv) -{ - piix_t *dev = (piix_t *) priv; - uint8_t valxor; - - uint16_t old_base = (dev->regs_ide[0x20] & 0xf0) | (dev->regs_ide[0x21] << 8); - if (func > 1) - return; - - if (func == 1) { /*IDE*/ - piix_log("PIIX IDE write: %02X %02X\n", addr, val); - valxor = val ^ dev->regs_ide[addr]; - - switch (addr) { - case 0x04: - dev->regs_ide[0x04] = (val & 5) | 2; - if (valxor & 0x01) { - ide_pri_disable(); - ide_sec_disable(); - if (val & 0x01) { - if (dev->regs_ide[0x41] & 0x80) - ide_pri_enable(); - if (dev->regs_ide[0x43] & 0x80) - ide_sec_enable(); - } - - piix_bus_master_handlers(dev, old_base); - } - break; - case 0x07: - dev->regs_ide[0x07] = val & 0x3e; - break; - case 0x0d: - dev->regs_ide[0x0d] = val; - break; - - case 0x20: - dev->regs_ide[0x20] = (val & ~0x0f) | 1; - if (valxor) - piix_bus_master_handlers(dev, old_base); - break; - case 0x21: - dev->regs_ide[0x21] = val; - if (valxor) - piix_bus_master_handlers(dev, old_base); - break; - - case 0x40: - dev->regs_ide[0x40] = val; - break; - case 0x41: - dev->regs_ide[0x41] = val; - if (valxor & 0x80) { - ide_pri_disable(); - if ((val & 0x80) && (dev->regs_ide[0x04] & 0x01)) - ide_pri_enable(); - } - break; - case 0x42: - dev->regs_ide[0x42] = val; - break; - case 0x43: - dev->regs_ide[0x43] = val; - if (valxor & 0x80) { - ide_sec_disable(); - if ((val & 0x80) && (dev->regs_ide[0x04] & 0x01)) - ide_sec_enable(); - } - break; - case 0x44: - if (dev->type >= 3) dev->regs_ide[0x44] = val; - break; - } - } else { - piix_log("PIIX writing value %02X to register %02X\n", val, addr); - valxor = val ^ dev->regs[addr]; - - if ((addr >= 0x0f) && (addr < 0x4c)) - return; - - switch (addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: - return; - - case 0x4c: - if (valxor) { - if (val & 0x80) { - if (dev->type == 3) - dma_alias_remove(); - else - dma_alias_remove_piix(); - } else - dma_alias_set(); - } - break; - case 0x4e: - keyboard_at_set_mouse_scan((val & 0x10) ? 1 : 0); - break; - case 0x60: - piix_log("Set IRQ routing: INT A -> %02X\n", val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTA, val & 0xf); - break; - case 0x61: - piix_log("Set IRQ routing: INT B -> %02X\n", val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTB, val & 0xf); - break; - case 0x62: - piix_log("Set IRQ routing: INT C -> %02X\n", val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTC, val & 0xf); - break; - case 0x63: - piix_log("Set IRQ routing: INT D -> %02X\n", val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTD, val & 0xf); - break; - case 0x6a: - if (dev->type == 3) - dev->regs[addr] = (val & 0xFD) | (dev->regs[addr] | 2); - else - dev->regs[addr] = (val & 0xFC) | (dev->regs[addr] | 3); - return; - case 0x70: - piix_log("Set MIRQ routing: MIRQ0 -> %02X\n", val); - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ0, val & 0xf); - break; - piix_log("MIRQ0 is %s\n", (val & 0x20) ? "disabled" : "enabled"); - case 0x71: - if (dev->type == 1) { - piix_log("Set MIRQ routing: MIRQ1 -> %02X\n", val); - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ1, val & 0xf); - } - break; - } - - dev->regs[addr] = val; - } -} - - -static uint8_t -piix_read(int func, int addr, void *priv) -{ - piix_t *dev = (piix_t *) priv; - - if ((func == 1) && (dev->type & 0x100)) /* PB640's PIIX has no IDE part. */ - return 0xff; - if (func > 1) - return 0xff; - - if (func == 1) { /*IDE*/ - if (addr == 4) - return (dev->regs_ide[addr] & 5) | 2; - else if (addr == 5) - return 0; - else if (addr == 6) - return 0x80; - else if (addr == 7) - return dev->regs_ide[addr] & 0x3E; - else if (addr == 0xD) - return dev->regs_ide[addr] & 0xF0; - else if (addr == 0x20) - return (dev->regs_ide[addr] & 0xF0) | 1; - else if (addr == 0x22) - return 0; - else if (addr == 0x23) - return 0; - else if (addr == 0x41) { - if (dev->type == 3) - return dev->regs_ide[addr] & 0xF3; - else - return dev->regs_ide[addr] & 0xB3; - } else if (addr == 0x43) { - if (dev->type == 3) - return dev->regs_ide[addr] & 0xF3; - else - return dev->regs_ide[addr] & 0xB3; - } else - return dev->regs_ide[addr]; - } else { - if ((addr & 0xFC) == 0x60) - return dev->regs[addr] & 0x8F; - - if (addr == 4) { - if (dev->type & 0x100) - return (dev->regs[addr] & 0x80) | 0x0F; - else - return (dev->regs[addr] & 0x80) | 7; - } else if (addr == 5) { - if (dev->type == 3) - return dev->regs[addr] & 1; - else - return 0; - } else if (addr == 6) - return dev->regs[addr] & 0x80; - else if (addr == 7) { - if (dev->type == 3) - return dev->regs[addr]; - else { - if (dev->type & 0x100) - return dev->regs[addr] & 0x02; - else - return dev->regs[addr] & 0x3E; - } - } else if (addr == 0x4E) - return (dev->regs[addr] & 0xEF) | keyboard_at_get_mouse_scan(); - else if (addr == 0x69) - return dev->regs[addr] & 0xFE; - else if (addr == 0x6A) { - if (dev->type == 3) - return dev->regs[addr] & 0xD1; - else - return dev->regs[addr] & 0x07; - } else if (addr == 0x6B) { - if (dev->type == 3) - return dev->regs[addr] & 0x80; - else - return 0; - } - else if (addr == 0x70) { - if (dev->type == 3) - return dev->regs[addr] & 0xEF; - else - return dev->regs[addr] & 0xCF; - } else if (addr == 0x71) { - if (dev->type == 3) - return 0; - else - return dev->regs[addr] & 0xCF; - } else if (addr == 0x76) { - if (dev->type == 3) - return dev->regs[addr] & 0x87; - else - return dev->regs[addr] & 0x8F; - } else if (addr == 0x77) { - if (dev->type == 3) - return dev->regs[addr] & 0x87; - else - return dev->regs[addr] & 0x8F; - } else if (addr == 0x80) { - if (dev->type == 3) - return dev->regs[addr] & 0x7F; - else if (dev->type == 1) - return 0; - } else if (addr == 0x82) { - if (dev->type == 3) - return dev->regs[addr] & 0x0F; - else - return 0; - } else if (addr == 0xA0) - return dev->regs[addr] & 0x1F; - else if (addr == 0xA3) { - if (dev->type == 3) - return dev->regs[addr] & 1; - else - return 0; - } else if (addr == 0xA7) { - if (dev->type == 3) - return dev->regs[addr]; - else - return dev->regs[addr] & 0xEF; - } else if (addr == 0xAB) { - if (dev->type == 3) - return dev->regs[addr]; - else - return dev->regs[addr] & 0xFE; - } else - return dev->regs[addr]; - } - - return 0; -} - - -static void -piix_bus_master_next_addr(piix_busmaster_t *dev) -{ - DMAPageRead(dev->ptr_cur, (uint8_t *)&(dev->addr), 4); - DMAPageRead(dev->ptr_cur + 4, (uint8_t *)&(dev->count), 4); - piix_log("PIIX Bus master DWORDs: %08X %08X\n", dev->addr, dev->count); - dev->eot = dev->count >> 31; - dev->count &= 0xfffe; - if (!dev->count) - dev->count = 65536; - dev->addr &= 0xfffffffe; - dev->ptr_cur += 8; -} - - -static void -piix_bus_master_write(uint16_t port, uint8_t val, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - int channel = (port & 8) ? 1 : 0; - - piix_log("PIIX Bus master BYTE write: %04X %02X\n", port, val); - - switch (port & 7) { - case 0: - piix_log("PIIX Cmd : val = %02X, old = %02X\n", val, dev->command); - if ((val & 1) && !(dev->command & 1)) { /*Start*/ - piix_log("PIIX Bus Master start on channel %i\n", channel); - dev->ptr_cur = dev->ptr; - piix_bus_master_next_addr(dev); - dev->status |= 1; - } - if (!(val & 1) && (dev->command & 1)) { /*Stop*/ - piix_log("PIIX Bus Master stop on channel %i\n", channel); - dev->status &= ~1; - } - - dev->command = val; - break; - case 2: - piix_log("PIIX Status: val = %02X, old = %02X\n", val, dev->status); - dev->status &= 0x07; - dev->status |= (val & 0x60); - if (val & 0x04) - dev->status &= ~0x04; - if (val & 0x02) - dev->status &= ~0x02; - break; - case 4: - dev->ptr = (dev->ptr & 0xffffff00) | (val & 0xfc); - dev->ptr %= (mem_size * 1024); - dev->ptr0 = val; - break; - case 5: - dev->ptr = (dev->ptr & 0xffff00fc) | (val << 8); - dev->ptr %= (mem_size * 1024); - break; - case 6: - dev->ptr = (dev->ptr & 0xff00fffc) | (val << 16); - dev->ptr %= (mem_size * 1024); - break; - case 7: - dev->ptr = (dev->ptr & 0x00fffffc) | (val << 24); - dev->ptr %= (mem_size * 1024); - break; - } -} - - -static void -piix_bus_master_writew(uint16_t port, uint16_t val, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - - piix_log("PIIX Bus master WORD write: %04X %04X\n", port, val); - - switch (port & 7) { - case 0: - case 2: - piix_bus_master_write(port, val & 0xff, priv); - break; - case 4: - dev->ptr = (dev->ptr & 0xffff0000) | (val & 0xfffc); - dev->ptr %= (mem_size * 1024); - dev->ptr0 = val & 0xff; - break; - case 6: - dev->ptr = (dev->ptr & 0x0000fffc) | (val << 16); - dev->ptr %= (mem_size * 1024); - break; - } -} - - -static void -piix_bus_master_writel(uint16_t port, uint32_t val, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - - piix_log("PIIX Bus master DWORD write: %04X %08X\n", port, val); - - switch (port & 7) { - case 0: - case 2: - piix_bus_master_write(port, val & 0xff, priv); - break; - case 4: - dev->ptr = (val & 0xfffffffc); - dev->ptr %= (mem_size * 1024); - dev->ptr0 = val & 0xff; - break; - } -} - - -static uint8_t -piix_bus_master_read(uint16_t port, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - - uint8_t ret = 0xff; - - switch (port & 7) { - case 0: - ret = dev->command; - break; - case 2: - ret = dev->status & 0x67; - break; - case 4: - ret = dev->ptr0; - break; - case 5: - ret = dev->ptr >> 8; - break; - case 6: - ret = dev->ptr >> 16; - break; - case 7: - ret = dev->ptr >> 24; - break; - } - - piix_log("PIIX Bus master BYTE read : %04X %02X\n", port, ret); - - return ret; -} - - -static uint16_t -piix_bus_master_readw(uint16_t port, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - - uint16_t ret = 0xffff; - - switch (port & 7) { - case 0: - case 2: - ret = (uint16_t) piix_bus_master_read(port, priv); - break; - case 4: - ret = dev->ptr0 | (dev->ptr & 0xff00); - break; - case 6: - ret = dev->ptr >> 16; - break; - } - - piix_log("PIIX Bus master WORD read : %04X %04X\n", port, ret); - - return ret; -} - - -static uint32_t -piix_bus_master_readl(uint16_t port, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - - uint32_t ret = 0xffffffff; - - switch (port & 7) { - case 0: - case 2: - ret = (uint32_t) piix_bus_master_read(port, priv); - break; - case 4: - ret = dev->ptr0 | (dev->ptr & 0xffffff00); - break; - } - - piix_log("PIIX Bus master DWORD read : %04X %08X\n", port, ret); - - return ret; -} - - -static int -piix_bus_master_dma_op(int channel, uint8_t *data, int transfer_length, int out, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - char *sop; - - int force_end = 0, buffer_pos = 0; - - sop = out ? "Writ" : "Read"; - - if (!(dev->status & 1)) - return 2; /*DMA disabled*/ - - piix_log("PIIX Bus master %s: %i bytes\n", out ? "read" : "write", transfer_length); - - while (1) { - if (dev->count <= transfer_length) { - piix_log("%sing %i bytes to %08X\n", sop, dev->count, dev->addr); - if (out) - DMAPageWrite(dev->addr, (uint8_t *)(data + buffer_pos), dev->count); - else - DMAPageRead(dev->addr, (uint8_t *)(data + buffer_pos), dev->count); - transfer_length -= dev->count; - buffer_pos += dev->count; - } else { - piix_log("%sing %i bytes to %08X\n", sop, transfer_length, dev->addr); - if (out) - DMAPageWrite(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length); - else - DMAPageRead(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length); - /* Increase addr and decrease count so that resumed transfers do not mess up. */ - dev->addr += transfer_length; - dev->count -= transfer_length; - transfer_length = 0; - force_end = 1; - } - - if (force_end) { - piix_log("Total transfer length smaller than sum of all blocks, partial block\n"); - dev->status &= ~2; - return 0; /* This block has exhausted the data to transfer and it was smaller than the count, break. */ - } else { - if (!transfer_length && !dev->eot) { - piix_log("Total transfer length smaller than sum of all blocks, full block\n"); - dev->status &= ~2; - return 0; /* We have exhausted the data to transfer but there's more blocks left, break. */ - } else if (transfer_length && dev->eot) { - piix_log("Total transfer length greater than sum of all blocks\n"); - dev->status |= 2; - return 1; /* There is data left to transfer but we have reached EOT - return with error. */ - } else if (dev->eot) { - piix_log("Regular EOT\n"); - dev->status &= ~3; - return 0; /* We have regularly reached EOT - clear status and break. */ - } else { - /* We have more to transfer and there are blocks left, get next block. */ - piix_bus_master_next_addr(dev); - } - } - } - return 0; -} - - -int -piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length, void *priv) -{ - return piix_bus_master_dma_op(channel, data, transfer_length, 1, priv); -} - - -int -piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length, void *priv) -{ - return piix_bus_master_dma_op(channel, data, transfer_length, 0, priv); -} - - -void -piix_bus_master_set_irq(int channel, void *priv) -{ - piix_busmaster_t *dev = (piix_busmaster_t *) priv; - dev->status &= ~4; - dev->status |= (channel >> 4); - - channel &= 0x01; - if (dev->status & 0x04) { - if (channel && pci_use_mirq(0)) - pci_set_mirq(0); - else - picint(1 << (14 + channel)); - } else { - if ((channel & 1) && pci_use_mirq(0)) - pci_clear_mirq(0); - else - picintc(1 << (14 + channel)); - } -} - - -static void -piix_bus_master_reset(piix_t *dev) -{ - uint8_t i; - - uint16_t old_base = (dev->regs_ide[0x20] & 0xf0) | (dev->regs_ide[0x21] << 8); - if (old_base) { - io_removehandler(old_base, 0x08, - piix_bus_master_read, piix_bus_master_readw, piix_bus_master_readl, - piix_bus_master_write, piix_bus_master_writew, piix_bus_master_writel, - &dev->bm[0]); - io_removehandler(old_base + 8, 0x08, - piix_bus_master_read, piix_bus_master_readw, piix_bus_master_readl, - piix_bus_master_write, piix_bus_master_writew, piix_bus_master_writel, - &dev->bm[1]); - } - - for (i = 0; i < 2; i++) { - dev->bm[i].command = 0x00; - dev->bm[i].status = 0x00; - dev->bm[i].ptr = dev->bm[i].ptr_cur = 0x00000000; - dev->bm[i].addr = 0x00000000; - dev->bm[i].ptr0 = 0x00; - dev->bm[i].count = dev->bm[i].eot = 0x00000000; - } -} - - -static void -piix_reset_hard(void *priv) -{ - piix_t *piix = (piix_t *) priv; - - piix_bus_master_reset(piix); - - memset(piix->regs, 0, 256); - memset(piix->regs_ide, 0, 256); - - piix->regs[0x00] = 0x86; piix->regs[0x01] = 0x80; /*Intel*/ - if (piix->type == 3) { - piix->regs[0x02] = 0x00; piix->regs[0x03] = 0x70; /*82371SB (PIIX3)*/ - } else { - piix->regs[0x02] = 0x2e; piix->regs[0x03] = 0x12; /*82371FB (PIIX)*/ - } - if (piix->type & 0x100) - piix->regs[0x04] = 0x06; - else - piix->regs[0x04] = 0x07; - piix->regs[0x05] = 0x00; - piix->regs[0x06] = 0x80; piix->regs[0x07] = 0x02; - if (piix->type & 0x100) - piix->regs[0x08] = 0x02; /*A0 stepping*/ - else - piix->regs[0x08] = 0x00; /*A0 stepping*/ - piix->regs[0x09] = 0x00; piix->regs[0x0a] = 0x01; piix->regs[0x0b] = 0x06; - if (piix->type & 0x100) - piix->regs[0x0e] = 0x00; /*Single-function device*/ - else - piix->regs[0x0e] = 0x80; /*Multi-function device*/ - piix->regs[0x4c] = 0x4d; - piix->regs[0x4e] = 0x03; - if (piix->type == 3) - piix->regs[0x4f] = 0x00; - piix->regs[0x60] = piix->regs[0x61] = piix->regs[0x62] = piix->regs[0x63] = 0x80; - piix->regs[0x69] = 0x02; - piix->regs[0x70] = 0xc0; - if (piix->type != 3) - piix->regs[0x71] = 0xc0; - piix->regs[0x76] = piix->regs[0x77] = 0x0c; - piix->regs[0x78] = 0x02; piix->regs[0x79] = 0x00; - if (piix->type == 3) { - piix->regs[0x80] = piix->regs[0x82] = 0x00; - } - piix->regs[0xa0] = 0x08; - piix->regs[0xa2] = piix->regs[0xa3] = 0x00; - piix->regs[0xa4] = piix->regs[0xa5] = piix->regs[0xa6] = piix->regs[0xa7] = 0x00; - piix->regs[0xa8] = 0x0f; - piix->regs[0xaa] = piix->regs[0xab] = 0x00; - piix->regs[0xac] = 0x00; - piix->regs[0xae] = 0x00; - - piix->regs_ide[0x00] = 0x86; piix->regs_ide[0x01] = 0x80; /*Intel*/ - if (piix->type == 3) { - piix->regs_ide[0x02] = 0x10; piix->regs_ide[0x03] = 0x70; /*82371SB (PIIX3)*/ - } else { - piix->regs_ide[0x02] = 0x30; piix->regs_ide[0x03] = 0x12; /*82371FB (PIIX)*/ - } - piix->regs_ide[0x04] = 0x03; piix->regs_ide[0x05] = 0x00; - piix->regs_ide[0x06] = 0x80; piix->regs_ide[0x07] = 0x02; - piix->regs_ide[0x08] = 0x00; - piix->regs_ide[0x09] = 0x80; piix->regs_ide[0x0a] = 0x01; piix->regs_ide[0x0b] = 0x01; - piix->regs_ide[0x0d] = 0x00; - piix->regs_ide[0x0e] = 0x00; - piix->regs_ide[0x20] = 0x01; piix->regs_ide[0x21] = piix->regs_ide[0x22] = piix->regs_ide[0x23] = 0x00; /*Bus master interface base address*/ - piix->regs_ide[0x40] = piix->regs_ide[0x42] = 0x00; - piix->regs_ide[0x41] = piix->regs_ide[0x43] = 0x00; - if (piix->type == 3) - piix->regs_ide[0x44] = 0x00; - - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - - pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); - if (piix->type != 3) - pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); - - ide_pri_disable(); - ide_sec_disable(); -} - - -static void -piix_reset(void *p) -{ - int i = 0; - - for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI) - cdrom_reset(cdrom[i]); - } - for (i = 0; i < ZIP_NUM; i++) { - if (zip_drives[i].bus_type == ZIP_BUS_ATAPI) - zip_reset(i); - } -} - - -static void -piix_close(void *p) -{ - piix_t *piix = (piix_t *)p; - - free(piix); -} - - -static void -*piix_init(const device_t *info) -{ - piix_t *piix = (piix_t *) malloc(sizeof(piix_t)); - memset(piix, 0, sizeof(piix_t)); - - device_add(&ide_pci_2ch_device); - - pci_add_card(7, piix_read, piix_write, piix); - - piix->type = info->local; - piix_reset_hard(piix); - - ide_set_bus_master(piix_bus_master_dma_read, piix_bus_master_dma_write, - piix_bus_master_set_irq, - &piix->bm[0], &piix->bm[1]); - - port_92_reset(); - - port_92_add(); - - dma_alias_set(); - - pci_enable_mirq(0); - pci_enable_mirq(1); - - return piix; -} - - -const device_t piix_device = -{ - "Intel 82371FB (PIIX)", - DEVICE_PCI, - 1, - piix_init, - piix_close, - piix_reset, - NULL, - NULL, - NULL, - NULL -}; - -const device_t piix_pb640_device = -{ - "Intel 82371FB (PIIX) (PB640)", - DEVICE_PCI, - 0x101, - piix_init, - piix_close, - piix_reset, - NULL, - NULL, - NULL, - NULL -}; - -const device_t piix3_device = -{ - "Intel 82371SB (PIIX3)", - DEVICE_PCI, - 3, - piix_init, - piix_close, - piix_reset, - NULL, - NULL, - NULL, - NULL -}; diff --git a/backup code/keyboard_at.c.old b/backup code/keyboard_at.c.old deleted file mode 100644 index 278b44c33..000000000 --- a/backup code/keyboard_at.c.old +++ /dev/null @@ -1,2097 +0,0 @@ -/* - * 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. - * - * Intel 8042 (AT keyboard controller) emulation. - * - * Version: @(#)keyboard_at.c 1.0.36 2018/05/12 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include -#include "86box.h" -#include "cpu/cpu.h" -#include "io.h" -#include "pic.h" -#include "pit.h" -#include "ppi.h" -#include "mem.h" -#include "rom.h" -#include "device.h" -#include "timer.h" -#include "machine/machine.h" -#include "machine/m_xt_xi8088.h" -#include "machine/m_at_t3100e.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" -#include "sound/sound.h" -#include "sound/snd_speaker.h" -#include "video/video.h" -#include "keyboard.h" - - -#define STAT_PARITY 0x80 -#define STAT_RTIMEOUT 0x40 -#define STAT_TTIMEOUT 0x20 -#define STAT_MFULL 0x20 -#define STAT_LOCK 0x10 -#define STAT_CD 0x08 -#define STAT_SYSFLAG 0x04 -#define STAT_IFULL 0x02 -#define STAT_OFULL 0x01 - -#define PS2_REFRESH_TIME (16LL * TIMER_USEC) - -#define CCB_UNUSED 0x80 -#define CCB_TRANSLATE 0x40 -#define CCB_PCMODE 0x20 -#define CCB_ENABLEKBD 0x10 -#define CCB_IGNORELOCK 0x08 -#define CCB_SYSTEM 0x04 -#define CCB_ENABLEMINT 0x02 -#define CCB_ENABLEKINT 0x01 - -#define CCB_MASK 0x68 -#define MODE_MASK 0x6C - -#define KBC_TYPE_ISA 0x00 -#define KBC_TYPE_PS2_1 0x01 -#define KBC_TYPE_PS2_2 0x02 -#define KBC_TYPE_MASK 0x03 - -#define KBC_VEN_GENERIC 0x00 -#define KBC_VEN_AMI 0x04 -#define KBC_VEN_IBM_MCA 0x08 -#define KBC_VEN_QUADTEL 0x0C -#define KBC_VEN_TOSHIBA 0x10 -#define KBC_VEN_MASK 0x1C - -typedef struct { - int initialized; - int want60, - wantirq, - wantirq12; - uint8_t command; - uint8_t status; - uint8_t mem[0x100]; - uint8_t out; - int out_new; - uint8_t secr_phase; - uint8_t mem_addr; - - uint8_t input_port, - output_port; - - uint8_t old_output_port; - - uint8_t key_command; - int key_wantdata; - - int last_irq; - - uint8_t last_scan_code; - - int dtrans; - int first_write; - - int64_t refresh_time; - int refresh; - - uint32_t flags; - uint8_t output_locked; - - int64_t pulse_cb; - uint8_t ami_stat; - - uint8_t (*write60_ven)(void *p, uint8_t val); - uint8_t (*write64_ven)(void *p, uint8_t val); -} atkbd_t; - - -/* bit 0 = repeat, bit 1 = makes break code? */ -uint8_t keyboard_set3_flags[512]; -uint8_t keyboard_set3_all_repeat; -uint8_t keyboard_set3_all_break; - -/* Bits 0 - 1 = scan code set, bit 6 = translate or not. */ -uint8_t keyboard_mode = 0x42; - -#ifdef ENABLE_KEYBOARD_AT_LOG -int keyboard_at_do_log = ENABLE_KEYBOARD_AT_LOG; -#endif - -int mouse_queue_start = 0, - mouse_queue_end = 0; - - -static uint8_t key_ctrl_queue[16]; -static int key_ctrl_queue_start = 0, - key_ctrl_queue_end = 0; -static uint8_t key_queue[16]; -static int key_queue_start = 0, - key_queue_end = 0; -static uint8_t mouse_queue[16]; -static void (*mouse_write)(uint8_t val, void *priv) = NULL; -static void *mouse_p = NULL; -static uint8_t sc_or = 0; -static atkbd_t *CurrentKbd = NULL; // FIXME: remove!!! --FvK - - -/* Non-translated to translated scan codes. */ -static const uint8_t nont_to_t[256] = { - 0xFF, 0x43, 0x41, 0x3F, 0x3D, 0x3B, 0x3C, 0x58, - 0x64, 0x44, 0x42, 0x40, 0x3E, 0x0F, 0x29, 0x59, - 0x65, 0x38, 0x2A, 0x70, 0x1D, 0x10, 0x02, 0x5A, - 0x66, 0x71, 0x2C, 0x1F, 0x1E, 0x11, 0x03, 0x5B, - 0x67, 0x2E, 0x2D, 0x20, 0x12, 0x05, 0x04, 0x5C, - 0x68, 0x39, 0x2F, 0x21, 0x14, 0x13, 0x06, 0x5D, - 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5E, - 0x6A, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5F, - 0x6B, 0x33, 0x25, 0x17, 0x18, 0x0B, 0x0A, 0x60, - 0x6C, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0C, 0x61, - 0x6D, 0x73, 0x28, 0x74, 0x1A, 0x0D, 0x62, 0x6E, - 0x3A, 0x36, 0x1C, 0x1B, 0x75, 0x2B, 0x63, 0x76, - 0x55, 0x56, 0x77, 0x78, 0x79, 0x7A, 0x0E, 0x7B, - 0x7C, 0x4F, 0x7D, 0x4B, 0x47, 0x7E, 0x7F, 0x6F, - 0x52, 0x53, 0x50, 0x4C, 0x4D, 0x48, 0x01, 0x45, - 0x57, 0x4E, 0x51, 0x4A, 0x37, 0x49, 0x46, 0x54, - 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, - 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, - 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, - 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, - 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, - 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, - 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, - 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, - 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, - 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, - 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF -}; - -static const scancode scancode_set1[512] = { - { { -1},{ -1} }, { { 0x01,-1},{ 0x81,-1} }, { { 0x02,-1},{ 0x82,-1} }, { { 0x03,-1},{ 0x83,-1} }, /*000*/ - { { 0x04,-1},{ 0x84,-1} }, { { 0x05,-1},{ 0x85,-1} }, { { 0x06,-1},{ 0x86,-1} }, { { 0x07,-1},{ 0x87,-1} }, /*004*/ - { { 0x08,-1},{ 0x88,-1} }, { { 0x09,-1},{ 0x89,-1} }, { { 0x0a,-1},{ 0x8a,-1} }, { { 0x0b,-1},{ 0x8b,-1} }, /*008*/ - { { 0x0c,-1},{ 0x8c,-1} }, { { 0x0d,-1},{ 0x8d,-1} }, { { 0x0e,-1},{ 0x8e,-1} }, { { 0x0f,-1},{ 0x8f,-1} }, /*00c*/ - { { 0x10,-1},{ 0x90,-1} }, { { 0x11,-1},{ 0x91,-1} }, { { 0x12,-1},{ 0x92,-1} }, { { 0x13,-1},{ 0x93,-1} }, /*010*/ - { { 0x14,-1},{ 0x94,-1} }, { { 0x15,-1},{ 0x95,-1} }, { { 0x16,-1},{ 0x96,-1} }, { { 0x17,-1},{ 0x97,-1} }, /*014*/ - { { 0x18,-1},{ 0x98,-1} }, { { 0x19,-1},{ 0x99,-1} }, { { 0x1a,-1},{ 0x9a,-1} }, { { 0x1b,-1},{ 0x9b,-1} }, /*018*/ - { { 0x1c,-1},{ 0x9c,-1} }, { { 0x1d,-1},{ 0x9d,-1} }, { { 0x1e,-1},{ 0x9e,-1} }, { { 0x1f,-1},{ 0x9f,-1} }, /*01c*/ - { { 0x20,-1},{ 0xa0,-1} }, { { 0x21,-1},{ 0xa1,-1} }, { { 0x22,-1},{ 0xa2,-1} }, { { 0x23,-1},{ 0xa3,-1} }, /*020*/ - { { 0x24,-1},{ 0xa4,-1} }, { { 0x25,-1},{ 0xa5,-1} }, { { 0x26,-1},{ 0xa6,-1} }, { { 0x27,-1},{ 0xa7,-1} }, /*024*/ - { { 0x28,-1},{ 0xa8,-1} }, { { 0x29,-1},{ 0xa9,-1} }, { { 0x2a,-1},{ 0xaa,-1} }, { { 0x2b,-1},{ 0xab,-1} }, /*028*/ - { { 0x2c,-1},{ 0xac,-1} }, { { 0x2d,-1},{ 0xad,-1} }, { { 0x2e,-1},{ 0xae,-1} }, { { 0x2f,-1},{ 0xaf,-1} }, /*02c*/ - { { 0x30,-1},{ 0xb0,-1} }, { { 0x31,-1},{ 0xb1,-1} }, { { 0x32,-1},{ 0xb2,-1} }, { { 0x33,-1},{ 0xb3,-1} }, /*030*/ - { { 0x34,-1},{ 0xb4,-1} }, { { 0x35,-1},{ 0xb5,-1} }, { { 0x36,-1},{ 0xb6,-1} }, { { 0x37,-1},{ 0xb7,-1} }, /*034*/ - { { 0x38,-1},{ 0xb8,-1} }, { { 0x39,-1},{ 0xb9,-1} }, { { 0x3a,-1},{ 0xba,-1} }, { { 0x3b,-1},{ 0xbb,-1} }, /*038*/ - { { 0x3c,-1},{ 0xbc,-1} }, { { 0x3d,-1},{ 0xbd,-1} }, { { 0x3e,-1},{ 0xbe,-1} }, { { 0x3f,-1},{ 0xbf,-1} }, /*03c*/ - { { 0x40,-1},{ 0xc0,-1} }, { { 0x41,-1},{ 0xc1,-1} }, { { 0x42,-1},{ 0xc2,-1} }, { { 0x43,-1},{ 0xc3,-1} }, /*040*/ - { { 0x44,-1},{ 0xc4,-1} }, { { 0x45,-1},{ 0xc5,-1} }, { { 0x46,-1},{ 0xc6,-1} }, { { 0x47,-1},{ 0xc7,-1} }, /*044*/ - { { 0x48,-1},{ 0xc8,-1} }, { { 0x49,-1},{ 0xc9,-1} }, { { 0x4a,-1},{ 0xca,-1} }, { { 0x4b,-1},{ 0xcb,-1} }, /*048*/ - { { 0x4c,-1},{ 0xcc,-1} }, { { 0x4d,-1},{ 0xcd,-1} }, { { 0x4e,-1},{ 0xce,-1} }, { { 0x4f,-1},{ 0xcf,-1} }, /*04c*/ - { { 0x50,-1},{ 0xd0,-1} }, { { 0x51,-1},{ 0xd1,-1} }, { { 0x52,-1},{ 0xd2,-1} }, { { 0x53,-1},{ 0xd3,-1} }, /*050*/ - { { 0x54,-1},{ 0xd4,-1} }, { { 0x55,-1},{ 0xd5,-1} }, { { 0x56,-1},{ 0xd6,-1} }, { { 0x57,-1},{ 0xd7,-1} }, /*054*/ - { { 0x58,-1},{ 0xd8,-1} }, { { 0x59,-1},{ 0xd9,-1} }, { { 0x5a,-1},{ 0xda,-1} }, { { 0x5b,-1},{ 0xdb,-1} }, /*058*/ - { { 0x5c,-1},{ 0xdc,-1} }, { { 0x5d,-1},{ 0xdd,-1} }, { { 0x5e,-1},{ 0xde,-1} }, { { 0x5f,-1},{ 0xdf,-1} }, /*05c*/ - { { 0x60,-1},{ 0xe0,-1} }, { { 0x61,-1},{ 0xe1,-1} }, { { 0x62,-1},{ 0xe2,-1} }, { { 0x63,-1},{ 0xe3,-1} }, /*060*/ - { { 0x64,-1},{ 0xe4,-1} }, { { 0x65,-1},{ 0xe5,-1} }, { { 0x66,-1},{ 0xe6,-1} }, { { 0x67,-1},{ 0xe7,-1} }, /*064*/ - { { 0x68,-1},{ 0xe8,-1} }, { { 0x69,-1},{ 0xe9,-1} }, { { 0x6a,-1},{ 0xea,-1} }, { { 0x6b,-1},{ 0xeb,-1} }, /*068*/ - { { 0x6c,-1},{ 0xec,-1} }, { { 0x6d,-1},{ 0xed,-1} }, { { 0x6e,-1},{ 0xee,-1} }, { { 0x6f,-1},{ 0xef,-1} }, /*06c*/ - { { 0x70,-1},{ 0xf0,-1} }, { { 0x71,-1},{ 0xf1,-1} }, { { 0x72,-1},{ 0xf2,-1} }, { { 0x73,-1},{ 0xf3,-1} }, /*070*/ - { { 0x74,-1},{ 0xf4,-1} }, { { 0x75,-1},{ 0xf5,-1} }, { { 0x76,-1},{ 0xf6,-1} }, { { 0x77,-1},{ 0xf7,-1} }, /*074*/ - { { 0x78,-1},{ 0xf8,-1} }, { { 0x79,-1},{ 0xf9,-1} }, { { 0x7a,-1},{ 0xfa,-1} }, { { 0x7b,-1},{ 0xfb,-1} }, /*078*/ - { { 0x7c,-1},{ 0xfc,-1} }, { { 0x7d,-1},{ 0xfd,-1} }, { { 0x7e,-1},{ 0xfe,-1} }, { { 0x7f,-1},{ 0xff,-1} }, /*07c*/ - - { { 0x80,-1},{ -1} }, { { 0x81,-1},{ -1} }, { { 0x82,-1},{ -1} }, { { -1},{ -1} }, /*080*/ - { { -1},{ -1} }, { { 0x85,-1},{ -1} }, { { 0x86,-1},{ -1} }, { { 0x87,-1},{ -1} }, /*084*/ - { { 0x88,-1},{ -1} }, { { 0x89,-1},{ -1} }, { { 0x8a,-1},{ -1} }, { { 0x8b,-1},{ -1} }, /*088*/ - { { 0x8c,-1},{ -1} }, { { 0x8d,-1},{ -1} }, { { 0x8e,-1},{ -1} }, { { 0x8f,-1},{ -1} }, /*08c*/ - { { 0x90,-1},{ -1} }, { { 0x91,-1},{ -1} }, { { 0x92,-1},{ -1} }, { { 0x93,-1},{ -1} }, /*090*/ - { { 0x94,-1},{ -1} }, { { 0x95,-1},{ -1} }, { { 0x96,-1},{ -1} }, { { 0x97,-1},{ -1} }, /*094*/ - { { 0x98,-1},{ -1} }, { { 0x99,-1},{ -1} }, { { 0x9a,-1},{ -1} }, { { 0x9b,-1},{ -1} }, /*098*/ - { { 0x9c,-1},{ -1} }, { { 0x9d,-1},{ -1} }, { { 0x9e,-1},{ -1} }, { { 0x9f,-1},{ -1} }, /*09c*/ - { { 0xa0,-1},{ -1} }, { { 0xa1,-1},{ -1} }, { { 0xa2,-1},{ -1} }, { { 0xa3,-1},{ -1} }, /*0a0*/ - { { 0xa4,-1},{ -1} }, { { 0xa5,-1},{ -1} }, { { 0xa6,-1},{ -1} }, { { 0xa7,-1},{ -1} }, /*0a4*/ - { { 0xa8,-1},{ -1} }, { { 0xa9,-1},{ -1} }, { { 0xaa,-1},{ -1} }, { { 0xab,-1},{ -1} }, /*0a8*/ - { { 0xac,-1},{ -1} }, { { 0xad,-1},{ -1} }, { { 0xae,-1},{ -1} }, { { 0xaf,-1},{ -1} }, /*0ac*/ - { { 0xb0,-1},{ -1} }, { { 0xb1,-1},{ -1} }, { { 0xb2,-1},{ -1} }, { { 0xb3,-1},{ -1} }, /*0b0*/ - { { 0xb4,-1},{ -1} }, { { 0xb5,-1},{ -1} }, { { 0xb6,-1},{ -1} }, { { 0xb7,-1},{ -1} }, /*0b4*/ - { { 0xb8,-1},{ -1} }, { { 0xb9,-1},{ -1} }, { { 0xba,-1},{ -1} }, { { 0xbb,-1},{ -1} }, /*0b8*/ - { { 0xbc,-1},{ -1} }, { { 0xbd,-1},{ -1} }, { { 0xbe,-1},{ -1} }, { { 0xbf,-1},{ -1} }, /*0bc*/ - { { 0xc0,-1},{ -1} }, { { 0xc1,-1},{ -1} }, { { 0xc2,-1},{ -1} }, { { 0xc3,-1},{ -1} }, /*0c0*/ - { { 0xc4,-1},{ -1} }, { { 0xc5,-1},{ -1} }, { { 0xc6,-1},{ -1} }, { { 0xc7,-1},{ -1} }, /*0c4*/ - { { 0xc8,-1},{ -1} }, { { 0xc9,-1},{ -1} }, { { 0xca,-1},{ -1} }, { { 0xcb,-1},{ -1} }, /*0c8*/ - { { 0xcc,-1},{ -1} }, { { 0xcd,-1},{ -1} }, { { 0xce,-1},{ -1} }, { { 0xcf,-1},{ -1} }, /*0cc*/ - { { 0xd0,-1},{ -1} }, { { 0xd1,-1},{ -1} }, { { 0xd2,-1},{ -1} }, { { 0xd3,-1},{ -1} }, /*0d0*/ - { { 0xd4,-1},{ -1} }, { { 0xd5,-1},{ -1} }, { { 0xd6,-1},{ -1} }, { { 0xd7,-1},{ -1} }, /*0d4*/ - { { 0xd8,-1},{ -1} }, { { 0xd9,-1},{ -1} }, { { 0xda,-1},{ -1} }, { { 0xdb,-1},{ -1} }, /*0d8*/ - { { 0xdc,-1},{ -1} }, { { 0xdd,-1},{ -1} }, { { 0xde,-1},{ -1} }, { { 0xdf,-1},{ -1} }, /*0dc*/ - { { 0xe0,-1},{ -1} }, { { 0xe1,-1},{ -1} }, { { 0xe2,-1},{ -1} }, { { 0xe3,-1},{ -1} }, /*0e0*/ - { { 0xe4,-1},{ -1} }, { { 0xe5,-1},{ -1} }, { { 0xe6,-1},{ -1} }, { { 0xe7,-1},{ -1} }, /*0e4*/ - { { 0xe8,-1},{ -1} }, { { 0xe9,-1},{ -1} }, { { 0xea,-1},{ -1} }, { { 0xeb,-1},{ -1} }, /*0e8*/ - { { 0xec,-1},{ -1} }, { { 0xed,-1},{ -1} }, { { 0xee,-1},{ -1} }, { { 0xef,-1},{ -1} }, /*0ec*/ - { { -1},{ -1} }, { { 0xf1,-1},{ -1} }, { { 0xf2,-1},{ -1} }, { { 0xf3,-1},{ -1} }, /*0f0*/ - { { 0xf4,-1},{ -1} }, { { 0xf5,-1},{ -1} }, { { 0xf6,-1},{ -1} }, { { 0xf7,-1},{ -1} }, /*0f4*/ - { { 0xf8,-1},{ -1} }, { { 0xf9,-1},{ -1} }, { { 0xfa,-1},{ -1} }, { { 0xfb,-1},{ -1} }, /*0f8*/ - { { 0xfc,-1},{ -1} }, { { 0xfd,-1},{ -1} }, { { 0xfe,-1},{ -1} }, { { 0xff,-1},{ -1} }, /*0fc*/ - - { {0xe1,0x1d,-1},{0xe1, 0x9d,-1} }, { {0xe0,0x01,-1},{0xe0, 0x81,-1} }, { {0xe0,0x02,-1},{0xe0, 0x82,-1} }, { {0xe0,0x03,-1},{0xe0, 0x83,-1} }, /*100*/ - { {0xe0,0x04,-1},{0xe0, 0x84,-1} }, { {0xe0,0x05,-1},{0xe0, 0x85,-1} }, { {0xe0,0x06,-1},{0xe0, 0x86,-1} }, { {0xe0,0x07,-1},{0xe0, 0x87,-1} }, /*104*/ - { {0xe0,0x08,-1},{0xe0, 0x88,-1} }, { {0xe0,0x09,-1},{0xe0, 0x89,-1} }, { {0xe0,0x0a,-1},{0xe0, 0x8a,-1} }, { {0xe0,0x0b,-1},{0xe0, 0x8b,-1} }, /*108*/ - { {0xe0,0x0c,-1},{0xe0, 0x8c,-1} }, { { -1},{ -1} }, { {0xe0,0x0e,-1},{0xe0, 0x8e,-1} }, { {0xe0,0x0f,-1},{0xe0, 0x8f,-1} }, /*10c*/ - { {0xe0,0x10,-1},{0xe0, 0x90,-1} }, { {0xe0,0x11,-1},{0xe0, 0x91,-1} }, { {0xe0,0x12,-1},{0xe0, 0x92,-1} }, { {0xe0,0x13,-1},{0xe0, 0x93,-1} }, /*110*/ - { {0xe0,0x14,-1},{0xe0, 0x94,-1} }, { {0xe0,0x15,-1},{0xe0, 0x95,-1} }, { {0xe0,0x16,-1},{0xe0, 0x96,-1} }, { {0xe0,0x17,-1},{0xe0, 0x97,-1} }, /*114*/ - { {0xe0,0x18,-1},{0xe0, 0x98,-1} }, { {0xe0,0x19,-1},{0xe0, 0x99,-1} }, { {0xe0,0x1a,-1},{0xe0, 0x9a,-1} }, { {0xe0,0x1b,-1},{0xe0, 0x9b,-1} }, /*118*/ - { {0xe0,0x1c,-1},{0xe0, 0x9c,-1} }, { {0xe0,0x1d,-1},{0xe0, 0x9d,-1} }, { {0xe0,0x1e,-1},{0xe0, 0x9e,-1} }, { {0xe0,0x1f,-1},{0xe0, 0x9f,-1} }, /*11c*/ - { {0xe0,0x20,-1},{0xe0, 0xa0,-1} }, { {0xe0,0x21,-1},{0xe0, 0xa1,-1} }, { {0xe0,0x22,-1},{0xe0, 0xa2,-1} }, { {0xe0,0x23,-1},{0xe0, 0xa3,-1} }, /*120*/ - { {0xe0,0x24,-1},{0xe0, 0xa4,-1} }, { {0xe0,0x25,-1},{0xe0, 0xa5,-1} }, { {0xe0,0x26,-1},{0xe0, 0xa6,-1} }, { { -1},{ -1} }, /*124*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*128*/ - { {0xe0,0x2c,-1},{0xe0, 0xac,-1} }, { {0xe0,0x2d,-1},{0xe0, 0xad,-1} }, { {0xe0,0x2e,-1},{0xe0, 0xae,-1} }, { {0xe0,0x2f,-1},{0xe0, 0xaf,-1} }, /*12c*/ - { {0xe0,0x30,-1},{0xe0, 0xb0,-1} }, { {0xe0,0x31,-1},{0xe0, 0xb1,-1} }, { {0xe0,0x32,-1},{0xe0, 0xb2,-1} }, { { -1},{ -1} }, /*130*/ - { {0xe0,0x34,-1},{0xe0, 0xb4,-1} }, { {0xe0,0x35,-1},{0xe0, 0xb5,-1} }, { { -1},{ -1} }, { {0xe0,0x37,-1},{0xe0, 0xb7,-1} }, /*134*/ - { {0xe0,0x38,-1},{0xe0, 0xb8,-1} }, { { -1},{ -1} }, { {0xe0,0x3a,-1},{0xe0, 0xba,-1} }, { {0xe0,0x3b,-1},{0xe0, 0xbb,-1} }, /*138*/ - { {0xe0,0x3c,-1},{0xe0, 0xbc,-1} }, { {0xe0,0x3d,-1},{0xe0, 0xbd,-1} }, { {0xe0,0x3e,-1},{0xe0, 0xbe,-1} }, { {0xe0,0x3f,-1},{0xe0, 0xbf,-1} }, /*13c*/ - { {0xe0,0x40,-1},{0xe0, 0xc0,-1} }, { {0xe0,0x41,-1},{0xe0, 0xc1,-1} }, { {0xe0,0x42,-1},{0xe0, 0xc2,-1} }, { {0xe0,0x43,-1},{0xe0, 0xc3,-1} }, /*140*/ - { {0xe0,0x44,-1},{0xe0, 0xc4,-1} }, { { -1},{ -1} }, { {0xe0,0x46,-1},{0xe0, 0xc6,-1} }, { {0xe0,0x47,-1},{0xe0, 0xc7,-1} }, /*144*/ - { {0xe0,0x48,-1},{0xe0, 0xc8,-1} }, { {0xe0,0x49,-1},{0xe0, 0xc9,-1} }, { { -1},{ -1} }, { {0xe0,0x4b,-1},{0xe0, 0xcb,-1} }, /*148*/ - { {0xe0,0x4c,-1},{0xe0, 0xcc,-1} }, { {0xe0,0x4d,-1},{0xe0, 0xcd,-1} }, { {0xe0,0x4e,-1},{0xe0, 0xce,-1} }, { {0xe0,0x4f,-1},{0xe0, 0xcf,-1} }, /*14c*/ - { {0xe0,0x50,-1},{0xe0, 0xd0,-1} }, { {0xe0,0x51,-1},{0xe0, 0xd1,-1} }, { {0xe0,0x52,-1},{0xe0, 0xd2,-1} }, { {0xe0,0x53,-1},{0xe0, 0xd3,-1} }, /*150*/ - { { -1},{ -1} }, { {0xe0,0x55,-1},{0xe0, 0xd5,-1} }, { { -1},{ -1} }, { {0xe0,0x57,-1},{0xe0, 0xd7,-1} }, /*154*/ - { {0xe0,0x58,-1},{0xe0, 0xd8,-1} }, { {0xe0,0x59,-1},{0xe0, 0xd9,-1} }, { {0xe0,0x5a,-1},{0xe0, 0xaa,-1} }, { {0xe0,0x5b,-1},{0xe0, 0xdb,-1} }, /*158*/ - { {0xe0,0x5c,-1},{0xe0, 0xdc,-1} }, { {0xe0,0x5d,-1},{0xe0, 0xdd,-1} }, { {0xe0,0x5e,-1},{0xe0, 0xee,-1} }, { {0xe0,0x5f,-1},{0xe0, 0xdf,-1} }, /*15c*/ - { { -1},{ -1} }, { {0xe0,0x61,-1},{0xe0, 0xe1,-1} }, { {0xe0,0x62,-1},{0xe0, 0xe2,-1} }, { {0xe0,0x63,-1},{0xe0, 0xe3,-1} }, /*160*/ - { {0xe0,0x64,-1},{0xe0, 0xe4,-1} }, { {0xe0,0x65,-1},{0xe0, 0xe5,-1} }, { {0xe0,0x66,-1},{0xe0, 0xe6,-1} }, { {0xe0,0x67,-1},{0xe0, 0xe7,-1} }, /*164*/ - { {0xe0,0x68,-1},{0xe0, 0xe8,-1} }, { {0xe0,0x69,-1},{0xe0, 0xe9,-1} }, { {0xe0,0x6a,-1},{0xe0, 0xea,-1} }, { {0xe0,0x6b,-1},{0xe0, 0xeb,-1} }, /*168*/ - { {0xe0,0x6c,-1},{0xe0, 0xec,-1} }, { {0xe0,0x6d,-1},{0xe0, 0xed,-1} }, { {0xe0,0x6e,-1},{0xe0, 0xee,-1} }, { { -1},{ -1} }, /*16c*/ - { {0xe0,0x70,-1},{0xe0, 0xf0,-1} }, { {0xe0,0x71,-1},{0xe0, 0xf1,-1} }, { {0xe0,0x72,-1},{0xe0, 0xf2,-1} }, { {0xe0,0x73,-1},{0xe0, 0xf3,-1} }, /*170*/ - { {0xe0,0x74,-1},{0xe0, 0xf4,-1} }, { {0xe0,0x75,-1},{0xe0, 0xf5,-1} }, { { -1},{ -1} }, { {0xe0,0x77,-1},{0xe0, 0xf7,-1} }, /*174*/ - { {0xe0,0x78,-1},{0xe0, 0xf8,-1} }, { {0xe0,0x79,-1},{0xe0, 0xf9,-1} }, { {0xe0,0x7a,-1},{0xe0, 0xfa,-1} }, { {0xe0,0x7b,-1},{0xe0, 0xfb,-1} }, /*178*/ - { {0xe0,0x7c,-1},{0xe0, 0xfc,-1} }, { {0xe0,0x7d,-1},{0xe0, 0xfd,-1} }, { {0xe0,0x7e,-1},{0xe0, 0xfe,-1} }, { {0xe0,0x7f,-1},{0xe0, 0xff,-1} }, /*17c*/ - - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*180*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*184*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*188*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*18c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*190*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*194*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*198*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*19c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1ac*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1cc*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1dc*/ - { { -1},{ -1} }, { {0xe0,0xe1,-1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xee,-1},{ -1} }, { { -1},{ -1} }, /*1ec*/ - { { -1},{ -1} }, { {0xe0,0xf1,-1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xfe,-1},{ -1} }, { {0xe0,0xff,-1},{ -1} } /*1fc*/ -}; - -static const scancode scancode_set2[512] = { - { { -1},{ -1} }, { { 0x76,-1},{ 0xF0,0x76,-1} }, { { 0x16,-1},{ 0xF0,0x16,-1} }, { { 0x1E,-1},{ 0xF0,0x1E,-1} }, /*000*/ - { { 0x26,-1},{ 0xF0,0x26,-1} }, { { 0x25,-1},{ 0xF0,0x25,-1} }, { { 0x2E,-1},{ 0xF0,0x2E,-1} }, { { 0x36,-1},{ 0xF0,0x36,-1} }, /*004*/ - { { 0x3D,-1},{ 0xF0,0x3D,-1} }, { { 0x3E,-1},{ 0xF0,0x3E,-1} }, { { 0x46,-1},{ 0xF0,0x46,-1} }, { { 0x45,-1},{ 0xF0,0x45,-1} }, /*008*/ - { { 0x4E,-1},{ 0xF0,0x4E,-1} }, { { 0x55,-1},{ 0xF0,0x55,-1} }, { { 0x66,-1},{ 0xF0,0x66,-1} }, { { 0x0D,-1},{ 0xF0,0x0D,-1} }, /*00c*/ - { { 0x15,-1},{ 0xF0,0x15,-1} }, { { 0x1D,-1},{ 0xF0,0x1D,-1} }, { { 0x24,-1},{ 0xF0,0x24,-1} }, { { 0x2D,-1},{ 0xF0,0x2D,-1} }, /*010*/ - { { 0x2C,-1},{ 0xF0,0x2C,-1} }, { { 0x35,-1},{ 0xF0,0x35,-1} }, { { 0x3C,-1},{ 0xF0,0x3C,-1} }, { { 0x43,-1},{ 0xF0,0x43,-1} }, /*014*/ - { { 0x44,-1},{ 0xF0,0x44,-1} }, { { 0x4D,-1},{ 0xF0,0x4D,-1} }, { { 0x54,-1},{ 0xF0,0x54,-1} }, { { 0x5B,-1},{ 0xF0,0x5B,-1} }, /*018*/ - { { 0x5A,-1},{ 0xF0,0x5A,-1} }, { { 0x14,-1},{ 0xF0,0x14,-1} }, { { 0x1C,-1},{ 0xF0,0x1C,-1} }, { { 0x1B,-1},{ 0xF0,0x1B,-1} }, /*01c*/ - { { 0x23,-1},{ 0xF0,0x23,-1} }, { { 0x2B,-1},{ 0xF0,0x2B,-1} }, { { 0x34,-1},{ 0xF0,0x34,-1} }, { { 0x33,-1},{ 0xF0,0x33,-1} }, /*020*/ - { { 0x3B,-1},{ 0xF0,0x3B,-1} }, { { 0x42,-1},{ 0xF0,0x42,-1} }, { { 0x4B,-1},{ 0xF0,0x4B,-1} }, { { 0x4C,-1},{ 0xF0,0x4C,-1} }, /*024*/ - { { 0x52,-1},{ 0xF0,0x52,-1} }, { { 0x0E,-1},{ 0xF0,0x0E,-1} }, { { 0x12,-1},{ 0xF0,0x12,-1} }, { { 0x5D,-1},{ 0xF0,0x5D,-1} }, /*028*/ - { { 0x1A,-1},{ 0xF0,0x1A,-1} }, { { 0x22,-1},{ 0xF0,0x22,-1} }, { { 0x21,-1},{ 0xF0,0x21,-1} }, { { 0x2A,-1},{ 0xF0,0x2A,-1} }, /*02c*/ - { { 0x32,-1},{ 0xF0,0x32,-1} }, { { 0x31,-1},{ 0xF0,0x31,-1} }, { { 0x3A,-1},{ 0xF0,0x3A,-1} }, { { 0x41,-1},{ 0xF0,0x41,-1} }, /*030*/ - { { 0x49,-1},{ 0xF0,0x49,-1} }, { { 0x4A,-1},{ 0xF0,0x4A,-1} }, { { 0x59,-1},{ 0xF0,0x59,-1} }, { { 0x7C,-1},{ 0xF0,0x7C,-1} }, /*034*/ - { { 0x11,-1},{ 0xF0,0x11,-1} }, { { 0x29,-1},{ 0xF0,0x29,-1} }, { { 0x58,-1},{ 0xF0,0x58,-1} }, { { 0x05,-1},{ 0xF0,0x05,-1} }, /*038*/ - { { 0x06,-1},{ 0xF0,0x06,-1} }, { { 0x04,-1},{ 0xF0,0x04,-1} }, { { 0x0C,-1},{ 0xF0,0x0C,-1} }, { { 0x03,-1},{ 0xF0,0x03,-1} }, /*03c*/ - { { 0x0B,-1},{ 0xF0,0x0B,-1} }, { { 0x83,-1},{ 0xF0,0x83,-1} }, { { 0x0A,-1},{ 0xF0,0x0A,-1} }, { { 0x01,-1},{ 0xF0,0x01,-1} }, /*040*/ - { { 0x09,-1},{ 0xF0,0x09,-1} }, { { 0x77,-1},{ 0xF0,0x77,-1} }, { { 0x7E,-1},{ 0xF0,0x7E,-1} }, { { 0x6C,-1},{ 0xF0,0x6C,-1} }, /*044*/ - { { 0x75,-1},{ 0xF0,0x75,-1} }, { { 0x7D,-1},{ 0xF0,0x7D,-1} }, { { 0x7B,-1},{ 0xF0,0x7B,-1} }, { { 0x6B,-1},{ 0xF0,0x6B,-1} }, /*048*/ - { { 0x73,-1},{ 0xF0,0x73,-1} }, { { 0x74,-1},{ 0xF0,0x74,-1} }, { { 0x79,-1},{ 0xF0,0x79,-1} }, { { 0x69,-1},{ 0xF0,0x69,-1} }, /*04c*/ - { { 0x72,-1},{ 0xF0,0x72,-1} }, { { 0x7A,-1},{ 0xF0,0x7A,-1} }, { { 0x70,-1},{ 0xF0,0x70,-1} }, { { 0x71,-1},{ 0xF0,0x71,-1} }, /*050*/ - { { 0x84,-1},{ 0xF0,0x84,-1} }, { { 0x60,-1},{ 0xF0,0x60,-1} }, { { 0x61,-1},{ 0xF0,0x61,-1} }, { { 0x78,-1},{ 0xF0,0x78,-1} }, /*054*/ - { { 0x07,-1},{ 0xF0,0x07,-1} }, { { 0x0F,-1},{ 0xF0,0x0F,-1} }, { { 0x17,-1},{ 0xF0,0x17,-1} }, { { 0x1F,-1},{ 0xF0,0x1F,-1} }, /*058*/ - { { 0x27,-1},{ 0xF0,0x27,-1} }, { { 0x2F,-1},{ 0xF0,0x2F,-1} }, { { 0x37,-1},{ 0xF0,0x37,-1} }, { { 0x3F,-1},{ 0xF0,0x3F,-1} }, /*05c*/ - { { 0x47,-1},{ 0xF0,0x47,-1} }, { { 0x4F,-1},{ 0xF0,0x4F,-1} }, { { 0x56,-1},{ 0xF0,0x56,-1} }, { { 0x5E,-1},{ 0xF0,0x5E,-1} }, /*060*/ - { { 0x08,-1},{ 0xF0,0x08,-1} }, { { 0x10,-1},{ 0xF0,0x10,-1} }, { { 0x18,-1},{ 0xF0,0x18,-1} }, { { 0x20,-1},{ 0xF0,0x20,-1} }, /*064*/ - { { 0x28,-1},{ 0xF0,0x28,-1} }, { { 0x30,-1},{ 0xF0,0x30,-1} }, { { 0x38,-1},{ 0xF0,0x38,-1} }, { { 0x40,-1},{ 0xF0,0x40,-1} }, /*068*/ - { { 0x48,-1},{ 0xF0,0x48,-1} }, { { 0x50,-1},{ 0xF0,0x50,-1} }, { { 0x57,-1},{ 0xF0,0x57,-1} }, { { 0x6F,-1},{ 0xF0,0x6F,-1} }, /*06c*/ - { { 0x13,-1},{ 0xF0,0x13,-1} }, { { 0x19,-1},{ 0xF0,0x19,-1} }, { { 0x39,-1},{ 0xF0,0x39,-1} }, { { 0x51,-1},{ 0xF0,0x51,-1} }, /*070*/ - { { 0x53,-1},{ 0xF0,0x53,-1} }, { { 0x5C,-1},{ 0xF0,0x5C,-1} }, { { 0x5F,-1},{ 0xF0,0x5F,-1} }, { { 0x62,-1},{ 0xF0,0x62,-1} }, /*074*/ - { { 0x63,-1},{ 0xF0,0x63,-1} }, { { 0x64,-1},{ 0xF0,0x64,-1} }, { { 0x65,-1},{ 0xF0,0x65,-1} }, { { 0x67,-1},{ 0xF0,0x67,-1} }, /*078*/ - { { 0x68,-1},{ 0xF0,0x68,-1} }, { { 0x6A,-1},{ 0xF0,0x6A,-1} }, { { 0x6D,-1},{ 0xF0,0x6D,-1} }, { { 0x6E,-1},{ 0xF0,0x6E,-1} }, /*07c*/ - - { { 0x80,-1},{ 0xf0,0x80,-1} }, { { 0x81,-1},{ 0xf0,0x81,-1} }, { { 0x82,-1},{ 0xf0,0x82,-1} }, { { -1},{ -1} }, /*080*/ - { { -1},{ -1} }, { { 0x85,-1},{ 0xf0,0x54,-1} }, { { 0x86,-1},{ 0xf0,0x86,-1} }, { { 0x87,-1},{ 0xf0,0x87,-1} }, /*084*/ - { { 0x88,-1},{ 0xf0,0x88,-1} }, { { 0x89,-1},{ 0xf0,0x89,-1} }, { { 0x8a,-1},{ 0xf0,0x8a,-1} }, { { 0x8b,-1},{ 0xf0,0x8b,-1} }, /*088*/ - { { 0x8c,-1},{ 0xf0,0x8c,-1} }, { { 0x8d,-1},{ 0xf0,0x8d,-1} }, { { 0x8e,-1},{ 0xf0,0x8e,-1} }, { { 0x8f,-1},{ 0xf0,0x8f,-1} }, /*08c*/ - { { 0x90,-1},{ 0xf0,0x90,-1} }, { { 0x91,-1},{ 0xf0,0x91,-1} }, { { 0x92,-1},{ 0xf0,0x92,-1} }, { { 0x93,-1},{ 0xf0,0x93,-1} }, /*090*/ - { { 0x94,-1},{ 0xf0,0x94,-1} }, { { 0x95,-1},{ 0xf0,0x95,-1} }, { { 0x96,-1},{ 0xf0,0x96,-1} }, { { 0x97,-1},{ 0xf0,0x97,-1} }, /*094*/ - { { 0x98,-1},{ 0xf0,0x98,-1} }, { { 0x99,-1},{ 0xf0,0x99,-1} }, { { 0x9a,-1},{ 0xf0,0x9a,-1} }, { { 0x9b,-1},{ 0xf0,0x9b,-1} }, /*098*/ - { { 0x9c,-1},{ 0xf0,0x9c,-1} }, { { 0x9d,-1},{ 0xf0,0x9d,-1} }, { { 0x9e,-1},{ 0xf0,0x9e,-1} }, { { 0x9f,-1},{ 0xf0,0x9f,-1} }, /*09c*/ - { { 0xa0,-1},{ 0xf0,0xa0,-1} }, { { 0xa1,-1},{ 0xf0,0xa1,-1} }, { { 0xa2,-1},{ 0xf0,0xa2,-1} }, { { 0xa3,-1},{ 0xf0,0xa3,-1} }, /*0a0*/ - { { 0xa4,-1},{ 0xf0,0xa4,-1} }, { { 0xa5,-1},{ 0xf0,0xa5,-1} }, { { 0xa6,-1},{ 0xf0,0xa6,-1} }, { { 0xa7,-1},{ 0xf0,0xa7,-1} }, /*0a4*/ - { { 0xa8,-1},{ 0xf0,0xa8,-1} }, { { 0xa9,-1},{ 0xf0,0xa9,-1} }, { { 0xaa,-1},{ 0xf0,0xaa,-1} }, { { 0xab,-1},{ 0xf0,0xab,-1} }, /*0a8*/ - { { 0xac,-1},{ 0xf0,0xac,-1} }, { { 0xad,-1},{ 0xf0,0xad,-1} }, { { 0xae,-1},{ 0xf0,0xae,-1} }, { { 0xaf,-1},{ 0xf0,0xaf,-1} }, /*0ac*/ - { { 0xb0,-1},{ 0xf0,0xb0,-1} }, { { 0xb1,-1},{ 0xf0,0xb1,-1} }, { { 0xb2,-1},{ 0xf0,0xb2,-1} }, { { 0xb3,-1},{ 0xf0,0xb3,-1} }, /*0b0*/ - { { 0xb4,-1},{ 0xf0,0xb4,-1} }, { { 0xb5,-1},{ 0xf0,0xb5,-1} }, { { 0xb6,-1},{ 0xf0,0xb6,-1} }, { { 0xb7,-1},{ 0xf0,0xb7,-1} }, /*0b4*/ - { { 0xb8,-1},{ 0xf0,0xb8,-1} }, { { 0xb9,-1},{ 0xf0,0xb9,-1} }, { { 0xba,-1},{ 0xf0,0xba,-1} }, { { 0xbb,-1},{ 0xf0,0xbb,-1} }, /*0b8*/ - { { 0xbc,-1},{ 0xf0,0xbc,-1} }, { { 0xbd,-1},{ 0xf0,0xbd,-1} }, { { 0xbe,-1},{ 0xf0,0xbe,-1} }, { { 0xbf,-1},{ 0xf0,0xbf,-1} }, /*0bc*/ - { { 0xc0,-1},{ 0xf0,0xc0,-1} }, { { 0xc1,-1},{ 0xf0,0xc1,-1} }, { { 0xc2,-1},{ 0xf0,0xc2,-1} }, { { 0xc3,-1},{ 0xf0,0xc3,-1} }, /*0c0*/ - { { 0xc4,-1},{ 0xf0,0xc4,-1} }, { { 0xc5,-1},{ 0xf0,0xc5,-1} }, { { 0xc6,-1},{ 0xf0,0xc6,-1} }, { { 0xc7,-1},{ 0xf0,0xc7,-1} }, /*0c4*/ - { { 0xc8,-1},{ 0xf0,0xc8,-1} }, { { 0xc9,-1},{ 0xf0,0xc9,-1} }, { { 0xca,-1},{ 0xf0,0xca,-1} }, { { 0xcb,-1},{ 0xf0,0xcb,-1} }, /*0c8*/ - { { 0xcc,-1},{ 0xf0,0xcc,-1} }, { { 0xcd,-1},{ 0xf0,0xcd,-1} }, { { 0xce,-1},{ 0xf0,0xce,-1} }, { { 0xcf,-1},{ 0xf0,0xcf,-1} }, /*0cc*/ - { { 0xd0,-1},{ 0xf0,0xd0,-1} }, { { 0xd1,-1},{ 0xf0,0xd0,-1} }, { { 0xd2,-1},{ 0xf0,0xd2,-1} }, { { 0xd3,-1},{ 0xf0,0xd3,-1} }, /*0d0*/ - { { 0xd4,-1},{ 0xf0,0xd4,-1} }, { { 0xd5,-1},{ 0xf0,0xd5,-1} }, { { 0xd6,-1},{ 0xf0,0xd6,-1} }, { { 0xd7,-1},{ 0xf0,0xd7,-1} }, /*0d4*/ - { { 0xd8,-1},{ 0xf0,0xd8,-1} }, { { 0xd9,-1},{ 0xf0,0xd9,-1} }, { { 0xda,-1},{ 0xf0,0xda,-1} }, { { 0xdb,-1},{ 0xf0,0xdb,-1} }, /*0d8*/ - { { 0xdc,-1},{ 0xf0,0xdc,-1} }, { { 0xdd,-1},{ 0xf0,0xdd,-1} }, { { 0xde,-1},{ 0xf0,0xde,-1} }, { { 0xdf,-1},{ 0xf0,0xdf,-1} }, /*0dc*/ - { { 0xe0,-1},{ 0xf0,0xe0,-1} }, { { 0xe1,-1},{ 0xf0,0xe1,-1} }, { { 0xe2,-1},{ 0xf0,0xe2,-1} }, { { 0xe3,-1},{ 0xf0,0xe3,-1} }, /*0e0*/ - { { 0xe4,-1},{ 0xf0,0xe4,-1} }, { { 0xe5,-1},{ 0xf0,0xe5,-1} }, { { 0xe6,-1},{ 0xf0,0xe6,-1} }, { { 0xe7,-1},{ 0xf0,0xe7,-1} }, /*0e4*/ - { { 0xe8,-1},{ 0xf0,0xe8,-1} }, { { 0xe9,-1},{ 0xf0,0xe9,-1} }, { { 0xea,-1},{ 0xf0,0xea,-1} }, { { 0xeb,-1},{ 0xf0,0xeb,-1} }, /*0e8*/ - { { 0xec,-1},{ 0xf0,0xec,-1} }, { { 0xed,-1},{ 0xf0,0xed,-1} }, { { 0xee,-1},{ 0xf0,0xee,-1} }, { { 0xef,-1},{ 0xf0,0xef,-1} }, /*0ec*/ - { { -1},{ -1} }, { { 0xf1,-1},{ 0xf0,0xf1,-1} }, { { 0xf2,-1},{ 0xf0,0xf2,-1} }, { { 0xf3,-1},{ 0xf0,0xf3,-1} }, /*0f0*/ - { { 0xf4,-1},{ 0xf0,0xf4,-1} }, { { 0xf5,-1},{ 0xf0,0xf5,-1} }, { { 0xf6,-1},{ 0xf0,0xf6,-1} }, { { 0xf7,-1},{ 0xf0,0xf7,-1} }, /*0f4*/ - { { 0xf8,-1},{ 0xf0,0xf8,-1} }, { { 0xf9,-1},{ 0xf0,0xf9,-1} }, { { 0xfa,-1},{ 0xf0,0xfa,-1} }, { { 0xfb,-1},{ 0xf0,0xfb,-1} }, /*0f8*/ - { { 0xfc,-1},{ 0xf0,0xfc,-1} }, { { 0xfd,-1},{ 0xf0,0xfd,-1} }, { { 0xfe,-1},{ 0xf0,0xfe,-1} }, { { 0xff,-1},{ 0xf0,0xff,-1} }, /*0fc*/ - - { {0xe1,0x14,-1},{0xe1,0xf0,0x14,-1} }, { {0xe0,0x76,-1},{0xe0,0xF0,0x76,-1} }, { {0xe0,0x16,-1},{0xe0,0xF0,0x16,-1} }, { {0xe0,0x1E,-1},{0xe0,0xF0,0x1E,-1} }, /*100*/ - { {0xe0,0x26,-1},{0xe0,0xF0,0x26,-1} }, { {0xe0,0x25,-1},{0xe0,0xF0,0x25,-1} }, { {0xe0,0x2E,-1},{0xe0,0xF0,0x2E,-1} }, { {0xe0,0x36,-1},{0xe0,0xF0,0x36,-1} }, /*104*/ - { {0xe0,0x3D,-1},{0xe0,0xF0,0x3D,-1} }, { {0xe0,0x3E,-1},{0xe0,0xF0,0x3E,-1} }, { {0xe0,0x46,-1},{0xe0,0xF0,0x46,-1} }, { {0xe0,0x45,-1},{0xe0,0xF0,0x45,-1} }, /*108*/ - { {0xe0,0x4E,-1},{0xe0,0xF0,0x4E,-1} }, { { -1},{ -1} }, { {0xe0,0x66,-1},{0xe0,0xF0,0x66,-1} }, { {0xe0,0x0D,-1},{0xe0,0xF0,0x0D,-1} }, /*10c*/ - { {0xe0,0x15,-1},{0xe0,0xF0,0x15,-1} }, { {0xe0,0x1D,-1},{0xe0,0xF0,0x1D,-1} }, { {0xe0,0x24,-1},{0xe0,0xF0,0x24,-1} }, { {0xe0,0x2D,-1},{0xe0,0xF0,0x2D,-1} }, /*110*/ - { {0xe0,0x2C,-1},{0xe0,0xF0,0x2C,-1} }, { {0xe0,0x35,-1},{0xe0,0xF0,0x35,-1} }, { {0xe0,0x3C,-1},{0xe0,0xF0,0x3C,-1} }, { {0xe0,0x43,-1},{0xe0,0xF0,0x43,-1} }, /*114*/ - { {0xe0,0x44,-1},{0xe0,0xF0,0x44,-1} }, { {0xe0,0x4D,-1},{0xe0,0xF0,0x4D,-1} }, { {0xe0,0x54,-1},{0xe0,0xF0,0x54,-1} }, { {0xe0,0x5B,-1},{0xe0,0xF0,0x5B,-1} }, /*118*/ - { {0xe0,0x5A,-1},{0xe0,0xF0,0x5A,-1} }, { {0xe0,0x14,-1},{0xe0,0xF0,0x14,-1} }, { {0xe0,0x1C,-1},{0xe0,0xF0,0x1C,-1} }, { {0xe0,0x1B,-1},{0xe0,0xF0,0x1B,-1} }, /*11c*/ - { {0xe0,0x23,-1},{0xe0,0xF0,0x23,-1} }, { {0xe0,0x2B,-1},{0xe0,0xF0,0x2B,-1} }, { {0xe0,0x34,-1},{0xe0,0xF0,0x34,-1} }, { {0xe0,0x33,-1},{0xe0,0xF0,0x33,-1} }, /*120*/ - { {0xe0,0x3B,-1},{0xe0,0xF0,0x3B,-1} }, { {0xe0,0x42,-1},{0xe0,0xF0,0x42,-1} }, { {0xe0,0x4B,-1},{0xe0,0xF0,0x4B,-1} }, { { -1},{ -1} }, /*124*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*128*/ - { {0xe0,0x1A,-1},{0xe0,0xF0,0x1A,-1} }, { {0xe0,0x22,-1},{0xe0,0xF0,0x22,-1} }, { {0xe0,0x21,-1},{0xe0,0xF0,0x21,-1} }, { {0xe0,0x2A,-1},{0xe0,0xF0,0x2A,-1} }, /*12c*/ - { {0xe0,0x32,-1},{0xe0,0xF0,0x32,-1} }, { {0xe0,0x31,-1},{0xe0,0xF0,0x31,-1} }, { {0xe0,0x3A,-1},{0xe0,0xF0,0x3A,-1} }, { { -1},{ -1} }, /*130*/ - { {0xe0,0x49,-1},{0xe0,0xF0,0x49,-1} }, { {0xe0,0x4A,-1},{0xe0,0xF0,0x4A,-1} }, { { -1},{ -1} }, { {0xe0,0x7C,-1},{0xe0,0xF0,0x7C,-1} }, /*134*/ - { {0xe0,0x11,-1},{0xe0,0xF0,0x11,-1} }, { { -1},{ -1} }, { {0xe0,0x58,-1},{0xe0,0xF0,0x58,-1} }, { {0xe0,0x05,-1},{0xe0,0xF0,0x05,-1} }, /*138*/ - { {0xe0,0x06,-1},{0xe0,0xF0,0x06,-1} }, { {0xe0,0x04,-1},{0xe0,0xF0,0x04,-1} }, { {0xe0,0x0C,-1},{0xe0,0xF0,0x0C,-1} }, { {0xe0,0x03,-1},{0xe0,0xF0,0x03,-1} }, /*13c*/ - { {0xe0,0x0B,-1},{0xe0,0xF0,0x0B,-1} }, { {0xe0,0x02,-1},{0xe0,0xF0,0x02,-1} }, { {0xe0,0x0A,-1},{0xe0,0xF0,0x0A,-1} }, { {0xe0,0x01,-1},{0xe0,0xF0,0x01,-1} }, /*140*/ - { {0xe0,0x09,-1},{0xe0,0xF0,0x09,-1} }, { { -1},{ -1} }, { {0xe0,0x7E,-1},{0xe0,0xF0,0x7E,-1} }, { {0xe0,0x6C,-1},{0xe0,0xF0,0x6C,-1} }, /*144*/ - { {0xe0,0x75,-1},{0xe0,0xF0,0x75,-1} }, { {0xe0,0x7D,-1},{0xe0,0xF0,0x7D,-1} }, { { -1},{ -1} }, { {0xe0,0x6B,-1},{0xe0,0xF0,0x6B,-1} }, /*148*/ - { {0xe0,0x73,-1},{0xe0,0xF0,0x73,-1} }, { {0xe0,0x74,-1},{0xe0,0xF0,0x74,-1} }, { {0xe0,0x79,-1},{0xe0,0xF0,0x79,-1} }, { {0xe0,0x69,-1},{0xe0,0xF0,0x69,-1} }, /*14c*/ - { {0xe0,0x72,-1},{0xe0,0xF0,0x72,-1} }, { {0xe0,0x7A,-1},{0xe0,0xF0,0x7A,-1} }, { {0xe0,0x70,-1},{0xe0,0xF0,0x70,-1} }, { {0xe0,0x71,-1},{0xe0,0xF0,0x71,-1} }, /*150*/ - { { -1},{ -1} }, { {0xe0,0x60,-1},{0xe0,0xF0,0x60,-1} }, { { -1},{ -1} }, { {0xe0,0x78,-1},{0xe0,0xF0,0x78,-1} }, /*154*/ - { {0xe0,0x07,-1},{0xe0,0xF0,0x07,-1} }, { {0xe0,0x0F,-1},{0xe0,0xF0,0x0F,-1} }, { {0xe0,0x17,-1},{0xe0,0xF0,0x17,-1} }, { {0xe0,0x1F,-1},{0xe0,0xF0,0x1F,-1} }, /*158*/ - { {0xe0,0x27,-1},{0xe0,0xF0,0x27,-1} }, { {0xe0,0x2F,-1},{0xe0,0xF0,0x2F,-1} }, { {0xe0,0x37,-1},{0xe0,0xF0,0x37,-1} }, { {0xe0,0x3F,-1},{0xe0,0xF0,0x3F,-1} }, /*15c*/ - { { -1},{ -1} }, { {0xe0,0x4F,-1},{0xe0,0xF0,0x4F,-1} }, { {0xe0,0x56,-1},{0xe0,0xF0,0x56,-1} }, { {0xe0,0x5E,-1},{0xe0,0xF0,0x5E,-1} }, /*160*/ - { {0xe0,0x08,-1},{0xe0,0xF0,0x08,-1} }, { {0xe0,0x10,-1},{0xe0,0xF0,0x10,-1} }, { {0xe0,0x18,-1},{0xe0,0xF0,0x18,-1} }, { {0xe0,0x20,-1},{0xe0,0xF0,0x20,-1} }, /*164*/ - { {0xe0,0x28,-1},{0xe0,0xF0,0x28,-1} }, { {0xe0,0x30,-1},{0xe0,0xF0,0x30,-1} }, { {0xe0,0x38,-1},{0xe0,0xF0,0x38,-1} }, { {0xe0,0x40,-1},{0xe0,0xF0,0x40,-1} }, /*168*/ - { {0xe0,0x48,-1},{0xe0,0xF0,0x48,-1} }, { {0xe0,0x50,-1},{0xe0,0xF0,0x50,-1} }, { {0xe0,0x57,-1},{0xe0,0xF0,0x57,-1} }, { { -1},{ -1} }, /*16c*/ - { {0xe0,0x13,-1},{0xe0,0xF0,0x13,-1} }, { {0xe0,0x19,-1},{0xe0,0xF0,0x19,-1} }, { {0xe0,0x39,-1},{0xe0,0xF0,0x39,-1} }, { {0xe0,0x51,-1},{0xe0,0xF0,0x51,-1} }, /*170*/ - { {0xe0,0x53,-1},{0xe0,0xF0,0x53,-1} }, { {0xe0,0x5C,-1},{0xe0,0xF0,0x5C,-1} }, { { -1},{ -1} }, { {0xe0,0x62,-1},{0xe0,0xF0,0x62,-1} }, /*174*/ - { {0xe0,0x63,-1},{0xe0,0xF0,0x63,-1} }, { {0xe0,0x64,-1},{0xe0,0xF0,0x64,-1} }, { {0xe0,0x65,-1},{0xe0,0xF0,0x65,-1} }, { {0xe0,0x67,-1},{0xe0,0xF0,0x67,-1} }, /*178*/ - { {0xe0,0x68,-1},{0xe0,0xF0,0x68,-1} }, { {0xe0,0x6A,-1},{0xe0,0xF0,0x6A,-1} }, { {0xe0,0x6D,-1},{0xe0,0xF0,0x6D,-1} }, { {0xe0,0x6E,-1},{0xe0,0xF0,0x6E,-1} }, /*17c*/ - - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*180*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*184*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*188*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*18c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*190*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*194*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*198*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*19c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1ac*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1cc*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1dc*/ - { { -1},{ -1} }, { {0xe0,0xe1,-1},{0xe0,0xF0,0xE1,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xee,-1},{0xe0,0xF0,0xEE,-1} }, { { -1},{ -1} }, /*1ec*/ - { { -1},{ -1} }, { {0xe0,0xf1,-1},{0xe0,0xF0,0xF1,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xfe,-1},{0xe0,0xF0,0xFE,-1} }, { {0xe0,0xff,-1},{0xe0,0xF0,0xFF,-1} } /*1fc*/ -}; - -static const scancode scancode_set3[512] = { - { { -1},{ -1} }, { { 0x08,-1},{ 0xf0,0x08,-1} }, { { 0x16,-1},{ 0xf0,0x16,-1} }, { { 0x1E,-1},{ 0xf0,0x1E,-1} }, /*000*/ - { { 0x26,-1},{ 0xf0,0x26,-1} }, { { 0x25,-1},{ 0xf0,0x25,-1} }, { { 0x2E,-1},{ 0xf0,0x2E,-1} }, { { 0x36,-1},{ 0xf0,0x36,-1} }, /*004*/ - { { 0x3D,-1},{ 0xf0,0x3D,-1} }, { { 0x3E,-1},{ 0xf0,0x3E,-1} }, { { 0x46,-1},{ 0xf0,0x46,-1} }, { { 0x45,-1},{ 0xf0,0x45,-1} }, /*008*/ - { { 0x4E,-1},{ 0xf0,0x4E,-1} }, { { 0x55,-1},{ 0xf0,0x55,-1} }, { { 0x66,-1},{ 0xf0,0x66,-1} }, { { 0x0D,-1},{ 0xf0,0x0D,-1} }, /*00c*/ - { { 0x15,-1},{ 0xf0,0x15,-1} }, { { 0x1D,-1},{ 0xf0,0x1D,-1} }, { { 0x24,-1},{ 0xf0,0x24,-1} }, { { 0x2D,-1},{ 0xf0,0x2D,-1} }, /*010*/ - { { 0x2C,-1},{ 0xf0,0x2C,-1} }, { { 0x35,-1},{ 0xf0,0x35,-1} }, { { 0x3C,-1},{ 0xf0,0x3C,-1} }, { { 0x43,-1},{ 0xf0,0x43,-1} }, /*014*/ - { { 0x44,-1},{ 0xf0,0x44,-1} }, { { 0x4D,-1},{ 0xf0,0x4D,-1} }, { { 0x54,-1},{ 0xf0,0x54,-1} }, { { 0x5B,-1},{ 0xf0,0x5B,-1} }, /*018*/ - { { 0x5A,-1},{ 0xf0,0x5A,-1} }, { { 0x11,-1},{ 0xf0,0x11,-1} }, { { 0x1C,-1},{ 0xf0,0x1C,-1} }, { { 0x1B,-1},{ 0xf0,0x1B,-1} }, /*01c*/ - { { 0x23,-1},{ 0xf0,0x23,-1} }, { { 0x2B,-1},{ 0xf0,0x2B,-1} }, { { 0x34,-1},{ 0xf0,0x34,-1} }, { { 0x33,-1},{ 0xf0,0x33,-1} }, /*020*/ - { { 0x3B,-1},{ 0xf0,0x3B,-1} }, { { 0x42,-1},{ 0xf0,0x42,-1} }, { { 0x4B,-1},{ 0xf0,0x4B,-1} }, { { 0x4C,-1},{ 0xf0,0x4C,-1} }, /*024*/ - { { 0x52,-1},{ 0xf0,0x52,-1} }, { { 0x0E,-1},{ 0xf0,0x0E,-1} }, { { 0x12,-1},{ 0xf0,0x12,-1} }, { { 0x5C,-1},{ 0xf0,0x5C,-1} }, /*028*/ - { { 0x1A,-1},{ 0xf0,0x1A,-1} }, { { 0x22,-1},{ 0xf0,0x22,-1} }, { { 0x21,-1},{ 0xf0,0x21,-1} }, { { 0x2A,-1},{ 0xf0,0x2A,-1} }, /*02c*/ - { { 0x32,-1},{ 0xf0,0x32,-1} }, { { 0x31,-1},{ 0xf0,0x31,-1} }, { { 0x3A,-1},{ 0xf0,0x3A,-1} }, { { 0x41,-1},{ 0xf0,0x41,-1} }, /*030*/ - { { 0x49,-1},{ 0xf0,0x49,-1} }, { { 0x4A,-1},{ 0xf0,0x4A,-1} }, { { 0x59,-1},{ 0xf0,0x59,-1} }, { { 0x7E,-1},{ 0xf0,0x7E,-1} }, /*034*/ - { { 0x19,-1},{ 0xf0,0x19,-1} }, { { 0x29,-1},{ 0xf0,0x29,-1} }, { { 0x14,-1},{ 0xf0,0x14,-1} }, { { 0x07,-1},{ 0xf0,0x07,-1} }, /*038*/ - { { 0x0F,-1},{ 0xf0,0x0F,-1} }, { { 0x17,-1},{ 0xf0,0x17,-1} }, { { 0x1F,-1},{ 0xf0,0x1F,-1} }, { { 0x27,-1},{ 0xf0,0x27,-1} }, /*03c*/ - { { 0x2F,-1},{ 0xf0,0x2F,-1} }, { { 0x37,-1},{ 0xf0,0x37,-1} }, { { 0x3F,-1},{ 0xf0,0x3F,-1} }, { { 0x47,-1},{ 0xf0,0x47,-1} }, /*040*/ - { { 0x4F,-1},{ 0xf0,0x4F,-1} }, { { 0x76,-1},{ 0xf0,0x76,-1} }, { { 0x5F,-1},{ 0xf0,0x5F,-1} }, { { 0x6C,-1},{ 0xf0,0x6C,-1} }, /*044*/ - { { 0x75,-1},{ 0xf0,0x75,-1} }, { { 0x7D,-1},{ 0xf0,0x7D,-1} }, { { 0x84,-1},{ 0xf0,0x84,-1} }, { { 0x6B,-1},{ 0xf0,0x6B,-1} }, /*048*/ - { { 0x73,-1},{ 0xf0,0x73,-1} }, { { 0x74,-1},{ 0xf0,0x74,-1} }, { { 0x7C,-1},{ 0xf0,0x7C,-1} }, { { 0x69,-1},{ 0xf0,0x69,-1} }, /*04c*/ - { { 0x72,-1},{ 0xf0,0x72,-1} }, { { 0x7A,-1},{ 0xf0,0x7A,-1} }, { { 0x70,-1},{ 0xf0,0x70,-1} }, { { 0x71,-1},{ 0xf0,0x71,-1} }, /*050*/ - { { 0x57,-1},{ 0xf0,0x57,-1} }, { { 0x60,-1},{ 0xf0,0x60,-1} }, { { -1},{ -1} }, { { 0x56,-1},{ 0xf0,0x56,-1} }, /*054*/ - { { 0x5E,-1},{ 0xf0,0x5E,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*058*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*05c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*060*/ - { { -1},{ -1} }, { { 0x10,-1},{ 0xf0,0x10,-1} }, { { 0x18,-1},{ 0xf0,0x18,-1} }, { { 0x20,-1},{ 0xf0,0x20,-1} }, /*064*/ - { { 0x28,-1},{ 0xf0,0x28,-1} }, { { 0x30,-1},{ 0xf0,0x30,-1} }, { { 0x38,-1},{ 0xf0,0x38,-1} }, { { 0x40,-1},{ 0xf0,0x40,-1} }, /*068*/ - { { 0x48,-1},{ 0xf0,0x48,-1} }, { { 0x50,-1},{ 0xf0,0x50,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*06c*/ - { { 0x87,-1},{ 0xf0,0x87,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { 0x51,-1},{ 0xf0,0x51,-1} }, /*070*/ - { { 0x53,-1},{ 0xf0,0x53,-1} }, { { 0x5C,-1},{ 0xf0,0x5C,-1} }, { { -1},{ -1} }, { { 0x62,-1},{ 0xf0,0x62,-1} }, /*074*/ - { { 0x63,-1},{ 0xf0,0x63,-1} }, { { 0x86,-1},{ 0xf0,0x86,-1} }, { { -1},{ -1} }, { { 0x85,-1},{ 0xf0,0x85,-1} }, /*078*/ - { { 0x68,-1},{ 0xf0,0x68,-1} }, { { 0x13,-1},{ 0xf0,0x13,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*07c*/ - - { { 0x80,-1},{ 0xf0,0x80,-1} }, { { 0x81,-1},{ 0xf0,0x81,-1} }, { { 0x82,-1},{ 0xf0,0x82,-1} }, { { -1},{ -1} }, /*080*/ - { { -1},{ -1} }, { { 0x85,-1},{ 0xf0,0x54,-1} }, { { 0x86,-1},{ 0xf0,0x86,-1} }, { { 0x87,-1},{ 0xf0,0x87,-1} }, /*084*/ - { { 0x88,-1},{ 0xf0,0x88,-1} }, { { 0x89,-1},{ 0xf0,0x89,-1} }, { { 0x8a,-1},{ 0xf0,0x8a,-1} }, { { 0x8b,-1},{ 0xf0,0x8b,-1} }, /*088*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { 0x8e,-1},{ 0xf0,0x8e,-1} }, { { 0x8f,-1},{ 0xf0,0x8f,-1} }, /*08c*/ - { { 0x90,-1},{ 0xf0,0x90,-1} }, { { 0x91,-1},{ 0xf0,0x91,-1} }, { { 0x92,-1},{ 0xf0,0x92,-1} }, { { 0x93,-1},{ 0xf0,0x93,-1} }, /*090*/ - { { 0x94,-1},{ 0xf0,0x94,-1} }, { { 0x95,-1},{ 0xf0,0x95,-1} }, { { 0x96,-1},{ 0xf0,0x96,-1} }, { { 0x97,-1},{ 0xf0,0x97,-1} }, /*094*/ - { { 0x98,-1},{ 0xf0,0x98,-1} }, { { 0x99,-1},{ 0xf0,0x99,-1} }, { { 0x9a,-1},{ 0xf0,0x9a,-1} }, { { 0x9b,-1},{ 0xf0,0x9b,-1} }, /*098*/ - { { 0x9c,-1},{ 0xf0,0x9c,-1} }, { { 0x9d,-1},{ 0xf0,0x9d,-1} }, { { 0x9e,-1},{ 0xf0,0x9e,-1} }, { { 0x9f,-1},{ 0xf0,0x9f,-1} }, /*09c*/ - { { 0xa0,-1},{ 0xf0,0xa0,-1} }, { { 0xa1,-1},{ 0xf0,0xa1,-1} }, { { 0xa2,-1},{ 0xf0,0xa2,-1} }, { { 0xa3,-1},{ 0xf0,0xa3,-1} }, /*0a0*/ - { { 0xa4,-1},{ 0xf0,0xa4,-1} }, { { 0xa5,-1},{ 0xf0,0xa5,-1} }, { { 0xa6,-1},{ 0xf0,0xa6,-1} }, { { 0xa7,-1},{ 0xf0,0xa7,-1} }, /*0a4*/ - { { 0xa8,-1},{ 0xf0,0xa8,-1} }, { { 0xa9,-1},{ 0xf0,0xa9,-1} }, { { 0xaa,-1},{ 0xf0,0xaa,-1} }, { { 0xab,-1},{ 0xf0,0xab,-1} }, /*0a8*/ - { { 0xac,-1},{ 0xf0,0xac,-1} }, { { 0xad,-1},{ 0xf0,0xad,-1} }, { { 0xae,-1},{ 0xf0,0xae,-1} }, { { 0xaf,-1},{ 0xf0,0xaf,-1} }, /*0ac*/ - { { 0xb0,-1},{ 0xf0,0xb0,-1} }, { { 0xb1,-1},{ 0xf0,0xb1,-1} }, { { 0xb2,-1},{ 0xf0,0xb2,-1} }, { { 0xb3,-1},{ 0xf0,0xb3,-1} }, /*0b0*/ - { { 0xb4,-1},{ 0xf0,0xb4,-1} }, { { 0xb5,-1},{ 0xf0,0xb5,-1} }, { { 0xb6,-1},{ 0xf0,0xb6,-1} }, { { 0xb7,-1},{ 0xf0,0xb7,-1} }, /*0b4*/ - { { 0xb8,-1},{ 0xf0,0xb8,-1} }, { { 0xb9,-1},{ 0xf0,0xb9,-1} }, { { 0xba,-1},{ 0xf0,0xba,-1} }, { { 0xbb,-1},{ 0xf0,0xbb,-1} }, /*0b8*/ - { { 0xbc,-1},{ 0xf0,0xbc,-1} }, { { 0xbd,-1},{ 0xf0,0xbd,-1} }, { { 0xbe,-1},{ 0xf0,0xbe,-1} }, { { 0xbf,-1},{ 0xf0,0xbf,-1} }, /*0bc*/ - { { 0xc0,-1},{ 0xf0,0xc0,-1} }, { { 0xc1,-1},{ 0xf0,0xc1,-1} }, { { 0xc2,-1},{ 0xf0,0xc2,-1} }, { { 0xc3,-1},{ 0xf0,0xc3,-1} }, /*0c0*/ - { { 0xc4,-1},{ 0xf0,0xc4,-1} }, { { 0xc5,-1},{ 0xf0,0xc5,-1} }, { { 0xc6,-1},{ 0xf0,0xc6,-1} }, { { 0xc7,-1},{ 0xf0,0xc7,-1} }, /*0c4*/ - { { 0xc8,-1},{ 0xf0,0xc8,-1} }, { { 0xc9,-1},{ 0xf0,0xc9,-1} }, { { 0xca,-1},{ 0xf0,0xca,-1} }, { { 0xcb,-1},{ 0xf0,0xcb,-1} }, /*0c8*/ - { { 0xcc,-1},{ 0xf0,0xcc,-1} }, { { 0xcd,-1},{ 0xf0,0xcd,-1} }, { { 0xce,-1},{ 0xf0,0xce,-1} }, { { 0xcf,-1},{ 0xf0,0xcf,-1} }, /*0cc*/ - { { 0xd0,-1},{ 0xf0,0xd0,-1} }, { { 0xd1,-1},{ 0xf0,0xd0,-1} }, { { 0xd2,-1},{ 0xf0,0xd2,-1} }, { { 0xd3,-1},{ 0xf0,0xd3,-1} }, /*0d0*/ - { { 0xd4,-1},{ 0xf0,0xd4,-1} }, { { 0xd5,-1},{ 0xf0,0xd5,-1} }, { { 0xd6,-1},{ 0xf0,0xd6,-1} }, { { 0xd7,-1},{ 0xf0,0xd7,-1} }, /*0d4*/ - { { 0xd8,-1},{ 0xf0,0xd8,-1} }, { { 0xd9,-1},{ 0xf0,0xd9,-1} }, { { 0xda,-1},{ 0xf0,0xda,-1} }, { { 0xdb,-1},{ 0xf0,0xdb,-1} }, /*0d8*/ - { { 0xdc,-1},{ 0xf0,0xdc,-1} }, { { 0xdd,-1},{ 0xf0,0xdd,-1} }, { { 0xde,-1},{ 0xf0,0xde,-1} }, { { 0xdf,-1},{ 0xf0,0xdf,-1} }, /*0dc*/ - { { 0xe0,-1},{ 0xf0,0xe0,-1} }, { { 0xe1,-1},{ 0xf0,0xe1,-1} }, { { 0xe2,-1},{ 0xf0,0xe2,-1} }, { { 0xe3,-1},{ 0xf0,0xe3,-1} }, /*0e0*/ - { { 0xe4,-1},{ 0xf0,0xe4,-1} }, { { 0xe5,-1},{ 0xf0,0xe5,-1} }, { { 0xe6,-1},{ 0xf0,0xe6,-1} }, { { 0xe7,-1},{ 0xf0,0xe7,-1} }, /*0e4*/ - { { 0xe8,-1},{ 0xf0,0xe8,-1} }, { { 0xe9,-1},{ 0xf0,0xe9,-1} }, { { 0xea,-1},{ 0xf0,0xea,-1} }, { { 0xeb,-1},{ 0xf0,0xeb,-1} }, /*0e8*/ - { { 0xec,-1},{ 0xf0,0xec,-1} }, { { 0xed,-1},{ 0xf0,0xed,-1} }, { { 0xee,-1},{ 0xf0,0xee,-1} }, { { 0xef,-1},{ 0xf0,0xef,-1} }, /*0ec*/ - { { -1},{ -1} }, { { 0xf1,-1},{ 0xf0,0xf1,-1} }, { { 0xf2,-1},{ 0xf0,0xf2,-1} }, { { 0xf3,-1},{ 0xf0,0xf3,-1} }, /*0f0*/ - { { 0xf4,-1},{ 0xf0,0xf4,-1} }, { { 0xf5,-1},{ 0xf0,0xf5,-1} }, { { 0xf6,-1},{ 0xf0,0xf6,-1} }, { { 0xf7,-1},{ 0xf0,0xf7,-1} }, /*0f4*/ - { { 0xf8,-1},{ 0xf0,0xf8,-1} }, { { 0xf9,-1},{ 0xf0,0xf9,-1} }, { { 0xfa,-1},{ 0xf0,0xfa,-1} }, { { 0xfb,-1},{ 0xf0,0xfb,-1} }, /*0f8*/ - { { 0xfc,-1},{ 0xf0,0xfc,-1} }, { { 0xfd,-1},{ 0xf0,0xfd,-1} }, { { 0xfe,-1},{ 0xf0,0xfe,-1} }, { { 0xff,-1},{ 0xf0,0xff,-1} }, /*0fc*/ - - { { 0x62,-1},{ 0xF0,0x62,-1} }, { {0xe0,0x76,-1},{0xe0,0xF0,0x76,-1} }, { {0xe0,0x16,-1},{0xe0,0xF0,0x16,-1} }, { {0xe0,0x1E,-1},{0xe0,0xF0,0x1E,-1} }, /*100*/ - { {0xe0,0x26,-1},{0xe0,0xF0,0x26,-1} }, { {0xe0,0x25,-1},{0xe0,0xF0,0x25,-1} }, { {0xe0,0x2E,-1},{0xe0,0xF0,0x2E,-1} }, { {0xe0,0x36,-1},{0xe0,0xF0,0x36,-1} }, /*104*/ - { {0xe0,0x3D,-1},{0xe0,0xF0,0x3D,-1} }, { {0xe0,0x3E,-1},{0xe0,0xF0,0x3E,-1} }, { {0xe0,0x46,-1},{0xe0,0xF0,0x46,-1} }, { {0xe0,0x45,-1},{0xe0,0xF0,0x45,-1} }, /*108*/ - { {0xe0,0x4E,-1},{0xe0,0xF0,0x4E,-1} }, { { -1},{ -1} }, { {0xe0,0x66,-1},{0xe0,0xF0,0x66,-1} }, { {0xe0,0x0D,-1},{0xe0,0xF0,0x0D,-1} }, /*10c*/ - { {0xe0,0x15,-1},{0xe0,0xF0,0x15,-1} }, { {0xe0,0x1D,-1},{0xe0,0xF0,0x1D,-1} }, { {0xe0,0x24,-1},{0xe0,0xF0,0x24,-1} }, { {0xe0,0x2D,-1},{0xe0,0xF0,0x2D,-1} }, /*110*/ - { {0xe0,0x2C,-1},{0xe0,0xF0,0x2C,-1} }, { {0xe0,0x35,-1},{0xe0,0xF0,0x35,-1} }, { {0xe0,0x3C,-1},{0xe0,0xF0,0x3C,-1} }, { {0xe0,0x43,-1},{0xe0,0xF0,0x43,-1} }, /*114*/ - { {0xe0,0x44,-1},{0xe0,0xF0,0x44,-1} }, { {0xe0,0x4D,-1},{0xe0,0xF0,0x4D,-1} }, { {0xe0,0x54,-1},{0xe0,0xF0,0x54,-1} }, { {0xe0,0x5B,-1},{0xe0,0xF0,0x5B,-1} }, /*118*/ - { { 0x79,-1},{ 0xf0,0x79,-1} }, { { 0x58,-1},{ 0xf0,0x58,-1} }, { {0xe0,0x1C,-1},{0xe0,0xF0,0x1C,-1} }, { {0xe0,0x1B,-1},{0xe0,0xF0,0x1B,-1} }, /*11c*/ - { {0xe0,0x23,-1},{0xe0,0xF0,0x23,-1} }, { {0xe0,0x2B,-1},{0xe0,0xF0,0x2B,-1} }, { {0xe0,0x34,-1},{0xe0,0xF0,0x34,-1} }, { {0xe0,0x33,-1},{0xe0,0xF0,0x33,-1} }, /*120*/ - { {0xe0,0x3B,-1},{0xe0,0xF0,0x3B,-1} }, { {0xe0,0x42,-1},{0xe0,0xF0,0x42,-1} }, { {0xe0,0x4B,-1},{0xe0,0xF0,0x4B,-1} }, { { -1},{ -1} }, /*124*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*128*/ - { {0xe0,0x1A,-1},{0xe0,0xF0,0x1A,-1} }, { {0xe0,0x22,-1},{0xe0,0xF0,0x22,-1} }, { {0xe0,0x21,-1},{0xe0,0xF0,0x21,-1} }, { {0xe0,0x2A,-1},{0xe0,0xF0,0x2A,-1} }, /*12c*/ - { {0xe0,0x32,-1},{0xe0,0xF0,0x32,-1} }, { {0xe0,0x31,-1},{0xe0,0xF0,0x31,-1} }, { {0xe0,0x3A,-1},{0xe0,0xF0,0x3A,-1} }, { { -1},{ -1} }, /*130*/ - { {0xe0,0x49,-1},{0xe0,0xF0,0x49,-1} }, { { 0x77,-1},{ 0xf0,0x77,-1} }, { { -1},{ -1} }, { { 0x57,-1},{ 0xf0,0x57,-1} }, /*134*/ - { { 0x39,-1},{ 0xf0,0x39,-1} }, { { -1},{ -1} }, { {0xe0,0x58,-1},{0xe0,0xF0,0x58,-1} }, { {0xe0,0x05,-1},{0xe0,0xF0,0x05,-1} }, /*138*/ - { {0xe0,0x06,-1},{0xe0,0xF0,0x06,-1} }, { {0xe0,0x04,-1},{0xe0,0xF0,0x04,-1} }, { {0xe0,0x0C,-1},{0xe0,0xF0,0x0C,-1} }, { {0xe0,0x03,-1},{0xe0,0xF0,0x03,-1} }, /*13c*/ - { {0xe0,0x0B,-1},{0xe0,0xF0,0x0B,-1} }, { {0xe0,0x02,-1},{0xe0,0xF0,0x02,-1} }, { {0xe0,0x0A,-1},{0xe0,0xF0,0x0A,-1} }, { {0xe0,0x01,-1},{0xe0,0xF0,0x01,-1} }, /*140*/ - { {0xe0,0x09,-1},{0xe0,0xF0,0x09,-1} }, { { -1},{ -1} }, { {0xe0,0x7E,-1},{0xe0,0xF0,0x7E,-1} }, { { 0x6E,-1},{ 0xf0,0x6E,-1} }, /*144*/ - { { 0x63,-1},{ 0xf0,0x63,-1} }, { { 0x6F,-1},{ 0xf0,0x6F,-1} }, { { -1},{ -1} }, { { 0x61,-1},{ 0xf0,0x61,-1} }, /*148*/ - { {0xe0,0x73,-1},{0xe0,0xF0,0x73,-1} }, { { 0x6A,-1},{ 0xf0,0x6A,-1} }, { {0xe0,0x79,-1},{0xe0,0xF0,0x79,-1} }, { { 0x65,-1},{ 0xf0,0x65,-1} }, /*14c*/ - { { 0x60,-1},{ 0xf0,0x60,-1} }, { { 0x6D,-1},{ 0xf0,0x6D,-1} }, { { 0x67,-1},{ 0xf0,0x67,-1} }, { { 0x64,-1},{ 0xf0,0x64,-1} }, /*150*/ - { { 0xd4,-1},{ 0xf0,0xD4,-1} }, { {0xe0,0x60,-1},{0xe0,0xF0,0x60,-1} }, { { -1},{ -1} }, { {0xe0,0x78,-1},{0xe0,0xF0,0x78,-1} }, /*154*/ - { {0xe0,0x07,-1},{0xe0,0xF0,0x07,-1} }, { {0xe0,0x0F,-1},{0xe0,0xF0,0x0F,-1} }, { {0xe0,0x17,-1},{0xe0,0xF0,0x17,-1} }, { { 0x8B,-1},{ 0xf0,0x8B,-1} }, /*158*/ - { { 0x8C,-1},{ 0xf0,0x8C,-1} }, { { 0x8D,-1},{ 0xf0,0x8D,-1} }, { { -1},{ -1} }, { { 0x7F,-1},{ 0xf0,0x7F,-1} }, /*15c*/ - { { -1},{ -1} }, { {0xe0,0x4F,-1},{0xe0,0xF0,0x4F,-1} }, { {0xe0,0x56,-1},{0xe0,0xF0,0x56,-1} }, { { -1},{ -1} }, /*160*/ - { {0xe0,0x08,-1},{0xe0,0xF0,0x08,-1} }, { {0xe0,0x10,-1},{0xe0,0xF0,0x10,-1} }, { {0xe0,0x18,-1},{0xe0,0xF0,0x18,-1} }, { {0xe0,0x20,-1},{0xe0,0xF0,0x20,-1} }, /*164*/ - { {0xe0,0x28,-1},{0xe0,0xF0,0x28,-1} }, { {0xe0,0x30,-1},{0xe0,0xF0,0x30,-1} }, { {0xe0,0x38,-1},{0xe0,0xF0,0x38,-1} }, { {0xe0,0x40,-1},{0xe0,0xF0,0x40,-1} }, /*168*/ - { {0xe0,0x48,-1},{0xe0,0xF0,0x48,-1} }, { {0xe0,0x50,-1},{0xe0,0xF0,0x50,-1} }, { {0xe0,0x57,-1},{0xe0,0xF0,0x57,-1} }, { { -1},{ -1} }, /*16c*/ - { {0xe0,0x13,-1},{0xe0,0xF0,0x13,-1} }, { {0xe0,0x19,-1},{0xe0,0xF0,0x19,-1} }, { {0xe0,0x39,-1},{0xe0,0xF0,0x39,-1} }, { {0xe0,0x51,-1},{0xe0,0xF0,0x51,-1} }, /*170*/ - { {0xe0,0x53,-1},{0xe0,0xF0,0x53,-1} }, { {0xe0,0x5C,-1},{0xe0,0xF0,0x5C,-1} }, { { -1},{ -1} }, { {0xe0,0x62,-1},{0xe0,0xF0,0x62,-1} }, /*174*/ - { {0xe0,0x63,-1},{0xe0,0xF0,0x63,-1} }, { {0xe0,0x64,-1},{0xe0,0xF0,0x64,-1} }, { {0xe0,0x65,-1},{0xe0,0xF0,0x65,-1} }, { {0xe0,0x67,-1},{0xe0,0xF0,0x67,-1} }, /*178*/ - { {0xe0,0x68,-1},{0xe0,0xF0,0x68,-1} }, { {0xe0,0x6A,-1},{0xe0,0xF0,0x6A,-1} }, { {0xe0,0x6D,-1},{0xe0,0xF0,0x6D,-1} }, { {0xe0,0x6E,-1},{0xe0,0xF0,0x6E,-1} }, /*17c*/ - - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*180*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*184*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*188*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*18c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*190*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*194*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*198*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*19c*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1a8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1ac*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1c8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1cc*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1d8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1dc*/ - { { -1},{ -1} }, { {0xe0,0xe1,-1},{0xe0,0xF0,0xE1,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1e8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xee,-1},{0xe0,0xF0,0xEE,-1} }, { { -1},{ -1} }, /*1ec*/ - { { -1},{ -1} }, { {0xe0,0xf1,-1},{0xe0,0xF0,0xF1,-1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f0*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f4*/ - { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, { { -1},{ -1} }, /*1f8*/ - { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xfe,-1},{0xe0,0xF0,0xFE,-1} }, { {0xe0,0xff,-1},{0xe0,0xF0,0xFF,-1} } /*1fc*/ -}; - - -static void -kbdlog(const char *fmt, ...) -{ -#ifdef ENABLE_KEYBOARD_AT_LOG - va_list ap; - - if (keyboard_at_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void -kbd_setmap(atkbd_t *kbd) -{ - switch (keyboard_mode & 3) { - case 1: - default: - keyboard_set_table(scancode_set1); - break; - - case 2: - keyboard_set_table(scancode_set2); - break; - - case 3: - keyboard_set_table(scancode_set3); - break; - } - - if (keyboard_mode & 0x20) - keyboard_set_table(scancode_set1); -} - - -static void -kbd_poll(void *priv) -{ - atkbd_t *kbd = (atkbd_t *)priv; - - keyboard_delay += (1000LL * TIMER_USEC); - - if ((kbd->out_new != -1) && !kbd->last_irq) { - kbd->wantirq = 0; - if (kbd->out_new & 0x100) { - kbdlog("ATkbd: want mouse data\n"); - if (kbd->mem[0] & 0x02) - picint(0x1000); - kbd->out = kbd->out_new & 0xff; - kbd->out_new = -1; - kbd->status |= STAT_OFULL; - kbd->status &= ~STAT_IFULL; - kbd->status |= STAT_MFULL; - kbd->last_irq = 0x1000; - } else { - kbdlog("ATkbd: want keyboard data\n"); - if (kbd->mem[0] & 0x01) - picint(2); - kbd->out = kbd->out_new & 0xff; - kbd->out_new = -1; - kbd->status |= STAT_OFULL; - kbd->status &= ~STAT_IFULL; - kbd->status &= ~STAT_MFULL; - kbd->last_irq = 2; - } - } - - if (kbd->out_new == -1 && !(kbd->status & STAT_OFULL) && - key_ctrl_queue_start != key_ctrl_queue_end) { - kbd->out_new = key_ctrl_queue[key_ctrl_queue_start]; - key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf; - } else if (!(kbd->status & STAT_OFULL) && kbd->out_new == -1/* && !(kbd->mem[0] & 0x20)*/ && - (mouse_queue_start != mouse_queue_end)) { - kbd->out_new = mouse_queue[mouse_queue_start] | 0x100; - mouse_queue_start = (mouse_queue_start + 1) & 0xf; - } else if (!(kbd->status&STAT_OFULL) && kbd->out_new == -1 && - !(kbd->mem[0]&0x10) && (key_queue_start != key_queue_end)) { - kbd->out_new = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; - } -} - - -static void -kbd_adddata(uint8_t val) -{ - key_ctrl_queue[key_ctrl_queue_end] = val; - key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0xf; -} - - -static void -kbd_adddata_vals(uint8_t *val, uint8_t len) -{ - int translate = (keyboard_mode & 0x40) && !(keyboard_mode & 0x20); - int i; - uint8_t or = 0; - uint8_t send; - - for (i = 0; i < len; i++) { - if (translate) { - if (val[i] == 0xf0) { - or = 0x80; - continue; - } - send = nont_to_t[val[i]] | or; - if (or == 0x80) - or = 0; - } else - send = val[i]; - kbdlog("%02X", send); - kbd_adddata(send); - if (i < (len - 1)) kbdlog(" "); - } - - if (translate) { - kbdlog(" original: ("); - for (i = 0; i < len; i++) { - kbdlog("%02X", val[i]); - if (i < (len - 1)) kbdlog(" "); - } - kbdlog(")"); - } - - kbdlog("\n"); -} - - -static void -kbd_adddata_keyboard(uint16_t val) -{ - int translate = (keyboard_mode & 0x40) && !(keyboard_mode & 0x20); - - uint8_t fake_shift[4]; - uint8_t num_lock = 0, shift_states = 0; - - keyboard_get_states(NULL, &num_lock, NULL); - shift_states = keyboard_get_shift() & STATE_SHIFT_MASK; - - /* Allow for scan code translation. */ - if (translate && (val == 0xf0)) { - kbdlog("Translate is on, F0 prefix detected\n"); - sc_or = 0x80; - return; - } - - /* Skip break code if translated make code has bit 7 set. */ - if (translate && (sc_or == 0x80) && (val & 0x80)) { - kbdlog("Translate is on, skipping scan code: %02X (original: F0 %02X)\n", nont_to_t[val], val); - sc_or = 0; - return; - } - - /* Test for T3100E 'Fn' key (Right Alt / Right Ctrl) */ - if (romset == ROM_T3100E && (keyboard_recv(0xb8) || keyboard_recv(0x9d))) - { - switch (val) - { - case 0x4f: t3100e_notify_set(0x01); break; /* End */ - case 0x50: t3100e_notify_set(0x02); break; /* Down */ - case 0x51: t3100e_notify_set(0x03); break; /* PgDn */ - case 0x52: t3100e_notify_set(0x04); break; /* Ins */ - case 0x53: t3100e_notify_set(0x05); break; /* Del */ - case 0x54: t3100e_notify_set(0x06); break; /* SysRQ */ - case 0x45: t3100e_notify_set(0x07); break; /* NumLock */ - case 0x46: t3100e_notify_set(0x08); break; /* ScrLock */ - case 0x47: t3100e_notify_set(0x09); break; /* Home */ - case 0x48: t3100e_notify_set(0x0A); break; /* Up */ - case 0x49: t3100e_notify_set(0x0B); break; /* PgUp */ - case 0x4A: t3100e_notify_set(0x0C); break; /* Keypad -*/ - case 0x4B: t3100e_notify_set(0x0D); break; /* Left */ - case 0x4C: t3100e_notify_set(0x0E); break; /* KP 5 */ - case 0x4D: t3100e_notify_set(0x0F); break; /* Right */ - } - } - - kbdlog("Translate is %s, ", translate ? "on" : "off"); - switch(val) { - case FAKE_LSHIFT_ON: - kbdlog("fake left shift on, scan code: "); - if (num_lock) { - if (shift_states) { - kbdlog("N/A (one or both shifts on)\n"); - break; - } else { - /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ - switch(keyboard_mode & 0x02) { - case 1: - fake_shift[0] = 0xe0; fake_shift[1] = 0x2a; - kbd_adddata_vals(fake_shift, 2); - break; - case 2: - fake_shift[0] = 0xe0; fake_shift[1] = 0x12; - kbd_adddata_vals(fake_shift, 2); - break; - default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); - break; - } - } - } else { - if (shift_states & STATE_LSHIFT) { - /* Num lock off and left shift pressed. */ - switch(keyboard_mode & 0x02) { - case 1: - fake_shift[0] = 0xe0; fake_shift[1] = 0xaa; - kbd_adddata_vals(fake_shift, 2); - break; - case 2: - fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x12; - kbd_adddata_vals(fake_shift, 3); - break; - default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); - break; - } - } - if (shift_states & STATE_RSHIFT) { - /* Num lock off and right shift pressed. */ - switch(keyboard_mode & 0x02) { - case 1: - fake_shift[0] = 0xe0; fake_shift[1] = 0xb6; - kbd_adddata_vals(fake_shift, 2); - break; - case 2: - fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x59; - kbd_adddata_vals(fake_shift, 3); - break; - default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); - break; - } - } - if (!shift_states) - kbdlog("N/A (both shifts off)\n"); - } - break; - case FAKE_LSHIFT_OFF: - kbdlog("fake left shift on, scan code: "); - if (num_lock) { - if (shift_states) { - kbdlog("N/A (one or both shifts on)\n"); - break; - } else { - /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ - switch(keyboard_mode & 0x02) { - case 1: - fake_shift[0] = 0xe0; fake_shift[1] = 0xaa; - kbd_adddata_vals(fake_shift, 2); - break; - case 2: - fake_shift[0] = 0xe0; fake_shift[1] = 0xf0; fake_shift[2] = 0x12; - kbd_adddata_vals(fake_shift, 3); - break; - default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); - break; - } - } - } else { - if (shift_states & STATE_LSHIFT) { - /* Num lock off and left shift pressed. */ - switch(keyboard_mode & 0x02) { - case 1: - fake_shift[0] = 0xe0; fake_shift[1] = 0x2a; - kbd_adddata_vals(fake_shift, 2); - break; - case 2: - fake_shift[0] = 0xe0; fake_shift[1] = 0x12; - kbd_adddata_vals(fake_shift, 2); - break; - default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); - break; - } - } - if (shift_states & STATE_RSHIFT) { - /* Num lock off and right shift pressed. */ - switch(keyboard_mode & 0x02) { - case 1: - fake_shift[0] = 0xe0; fake_shift[1] = 0x36; - kbd_adddata_vals(fake_shift, 2); - break; - case 2: - fake_shift[0] = 0xe0; fake_shift[1] = 0x59; - kbd_adddata_vals(fake_shift, 2); - break; - default: - kbdlog("N/A (scan code set %i)\n", keyboard_mode & 0x02); - break; - } - } - if (!shift_states) - kbdlog("N/A (both shifts off)\n"); - } - break; - default: - kbdlog("scan code: "); - if (translate) { - kbdlog("%02X (original: ", (nont_to_t[val] | sc_or)); - if (sc_or == 0x80) - kbdlog("F0 "); - kbdlog("%02X)\n", val); - } else - kbdlog("%02X\n", val); - - key_queue[key_queue_end] = (translate ? (nont_to_t[val] | sc_or) : val); - key_queue_end = (key_queue_end + 1) & 0xf; - break; - } - - if (sc_or == 0x80) sc_or = 0; -} - - -static void -kbd_output_write(atkbd_t *kbd, uint8_t val) -{ - kbdlog("Write output port: %02X (old: %02X)\n", val, kbd->output_port); - if ((kbd->output_port ^ val) & 0x20) { /*IRQ 12*/ - if (val & 0x20) - picint(1 << 12); - else - picintc(1 << 12); - } - if ((kbd->output_port ^ val) & 0x10) { /*IRQ 1*/ - if (val & 0x10) - picint(1 << 1); - else - picintc(1 << 1); - } - if ((kbd->output_port ^ val) & 0x02) { /*A20 enable change*/ - mem_a20_key = val & 0x02; - mem_a20_recalc(); - flushmmucache(); - } - if ((kbd->output_port ^ val) & 0x01) { /*Reset*/ - if (! (val & 0x01)) { - /* Pin 0 selected. */ - softresetx86(); /*Pulse reset!*/ - cpu_set_edx(); - } - } - kbd->output_port = val; -} - - -static void -kbd_cmd_write(atkbd_t *kbd, uint8_t val) -{ - kbdlog("Write command byte: %02X (old: %02X)\n", val, kbd->mem[0]); - - if ((val & 1) && (kbd->status & STAT_OFULL)) - kbd->wantirq = 1; - if (!(val & 1) && kbd->wantirq) - kbd->wantirq = 0; - - /* PS/2 type 2 keyboard controllers always force the XLAT bit to 0. */ - if ((kbd->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2) { - val &= ~CCB_TRANSLATE; - kbd->mem[0] &= ~CCB_TRANSLATE; - } - - /* Scan code translate ON/OFF. */ - keyboard_mode &= 0x93; - keyboard_mode |= (val & MODE_MASK); - - keyboard_scan = !(val & 0x10); - kbdlog("ATkbd: keyboard is now %s\n", mouse_scan ? "enabled" : "disabled"); - kbdlog("ATkbd: keyboard interrupt is now %s\n", (val & 0x01) ? "enabled" : "disabled"); - - /* ISA AT keyboard controllers use bit 5 for keyboard mode (1 = PC/XT, 2 = AT); - PS/2 (and EISA/PCI) keyboard controllers use it as the PS/2 mouse enable switch. */ - if (((kbd->flags & KBC_VEN_MASK) == KBC_VEN_AMI) || ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) { - keyboard_mode &= ~CCB_PCMODE; - - mouse_scan = !(val & 0x20); - kbdlog("ATkbd: mouse is now %s\n", mouse_scan ? "enabled" : "disabled"); - - kbdlog("ATkbd: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled"); - } -} - - -static void -kbd_output_pulse(atkbd_t *kbd, uint8_t mask) -{ - if (mask != 0xF) { - kbd->old_output_port = kbd->output_port & ~(0xF0 | mask); - kbd_output_write(kbd, kbd->output_port & (0xF0 | mask)); - kbd->pulse_cb = 6LL * TIMER_USEC; - } -} - - -static void -kbd_pulse_poll(void *p) -{ - atkbd_t *kbd = (atkbd_t *) p; - - kbd_output_write(kbd, kbd->output_port | kbd->old_output_port); - kbd->pulse_cb = 0LL; -} - - -static void -kbd_keyboard_set(atkbd_t *kbd, uint8_t enable) -{ - kbd->mem[0] &= 0xef; - kbd->mem[0] |= (enable ? 0x00 : 0x10); - keyboard_scan = enable; -} - - -static void -kbd_mouse_set(atkbd_t *kbd, uint8_t enable) -{ - kbd->mem[0] &= 0xdf; - kbd->mem[0] |= (enable ? 0x00 : 0x20); - mouse_scan = enable; -} - - -static uint8_t -kbd_write64_generic(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch (val) { - case 0xa4: /*Check if password installed*/ - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: check if password installed\n"); - kbd_adddata(0xf1); - return 0; - } else - kbdlog("ATkbd: bad command A4\n"); - break; - case 0xa7: /*Disable mouse port*/ - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: disable mouse port\n"); - kbd_mouse_set(kbd, 0); - return 0; - } else - kbdlog("ATkbd: bad command A7\n"); - break; - case 0xa8: /*Enable mouse port*/ - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: enable mouse port\n"); - kbd_mouse_set(kbd, 1); - return 0; - } else - kbdlog("ATkbd: bad command A8\n"); - break; - case 0xa9: /*Test mouse port*/ - kbdlog("ATkbd: test mouse port\n"); - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - if (mouse_write) - kbd_adddata(0x00); /*no error*/ - else - kbd_adddata(0xff); /*no mouse*/ - return 0; - } else - kbdlog("ATkbd: bad command A9\n"); - break; - case 0xaf: /*Read keyboard version*/ - kbdlog("ATkbd: read keyboard version\n"); - kbd_adddata(0x00); - return 0; - case 0xc0: /*Read input port*/ - kbdlog("ATkbd: read input port\n"); - - kbd_adddata(kbd->input_port | 4 | fdc_ps1_525()); - kbd->input_port = ((kbd->input_port + 1) & 3) | (kbd->input_port & 0xfc) | fdc_ps1_525(); - return 0; - case 0xd3: /*Write mouse output buffer*/ - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: write mouse output buffer\n"); - kbd->want60 = 1; - return 0; - } - break; - case 0xd4: /*Write to mouse*/ - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { - kbdlog("ATkbd: write to mouse\n"); - kbd->want60 = 1; - return 0; - } - break; - case 0xf0: case 0xf1: case 0xf2: case 0xf3: - case 0xf4: case 0xf5: case 0xf6: case 0xf7: - case 0xf8: case 0xf9: case 0xfa: case 0xfb: - case 0xfc: case 0xfd: case 0xfe: case 0xff: - // kbdlog("ATkbd: pulse %01X\n", val & 0x0f); - kbd_output_pulse(kbd, val & 0x0f); - return 0; - } - - return 1; -} - - -static uint8_t -kbd_write60_ami(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch(kbd->command) { - /* 0x40 - 0x5F are aliases for 0x60-0x7F */ - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - case 0x48: case 0x49: case 0x4a: case 0x4b: - case 0x4c: case 0x4d: case 0x4e: case 0x4f: - case 0x50: case 0x51: case 0x52: case 0x53: - case 0x54: case 0x55: case 0x56: case 0x57: - case 0x58: case 0x59: case 0x5a: case 0x5b: - case 0x5c: case 0x5d: case 0x5e: case 0x5f: - kbdlog("AMI - alias write to register %08X\n", kbd->command); - kbd->mem[kbd->command & 0x1f] = val; - if (kbd->command == 0x60) - kbd_cmd_write(kbd, val); - return 0; - case 0xaf: /*AMI - set extended controller RAM*/ - kbdlog("AMI - set extended controller RAM\n"); - if (kbd->secr_phase == 1) { - kbd->mem_addr = val; - kbd->want60 = 1; - kbd->secr_phase = 2; - } else if (kbd->secr_phase == 2) { - kbd->mem[kbd->mem_addr] = val; - kbd->secr_phase = 0; - } - return 0; - case 0xcb: /*AMI - set keyboard mode*/ - kbdlog("AMI - set keyboard mode\n"); - return 0; - } - - return 1; -} - - -static uint8_t -kbd_write64_ami(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch (val) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x04: case 0x05: case 0x06: case 0x07: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - case 0x10: case 0x11: case 0x12: case 0x13: - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x18: case 0x19: case 0x1a: case 0x1b: - case 0x1c: case 0x1d: case 0x1e: case 0x1f: - kbdlog("AMI - alias read from register %08X\n", val); - kbd_adddata(kbd->mem[val]); - return 0; - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - case 0x48: case 0x49: case 0x4a: case 0x4b: - case 0x4c: case 0x4d: case 0x4e: case 0x4f: - case 0x50: case 0x51: case 0x52: case 0x53: - case 0x54: case 0x55: case 0x56: case 0x57: - case 0x58: case 0x59: case 0x5a: case 0x5b: - case 0x5c: case 0x5d: case 0x5e: case 0x5f: - kbdlog("AMI - alias write to register %08X\n", kbd->command); - kbd->want60 = 1; - return 0; - case 0xa1: /*AMI - get controller version*/ - kbdlog("AMI - get controller version\n"); - return 0; - case 0xa2: /*AMI - reset keyboard controller lines P22 and P23 low*/ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - reset keyboard controller lines P22 and P23 low\n"); - kbd_output_write(kbd, kbd->output_port & 0xf3); - kbd_adddata(0x00); - return 0; - } - break; - case 0xa3: /*AMI - set keyboard controller lines P22 and P23 high*/ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - set keyboard controller lines P22 and P23 high\n"); - kbd_output_write(kbd, kbd->output_port | 0x0c); - kbd_adddata(0x00); - return 0; - } - break; - case 0xa4: /* AMI - write clock = low */ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - write clock = low\n"); - kbd->ami_stat &= 0xfe; - return 0; - } - break; - case 0xa5: /* AMI - write clock = high */ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - write clock = high\n"); - kbd->ami_stat |= 0x01; - return 0; - } - break; - case 0xa6: /* AMI - read clock */ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - read clock\n"); - kbd_adddata(!!(kbd->ami_stat & 1)); - return 0; - } - break; - case 0xa7: /* AMI - write cache bad */ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - write cache bad\n"); - kbd->ami_stat &= 0xfd; - return 0; - } - break; - case 0xa8: /* AMI - write cache good */ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - write cache good\n"); - kbd->ami_stat |= 0x02; - return 0; - } - break; - case 0xa9: /* AMI - read cache */ - if ((kbd->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1) { - kbdlog("AMI - read cache\n"); - kbd_adddata(!!(kbd->ami_stat & 2)); - return 0; - } - break; - case 0xaf: /*Set extended controller RAM*/ - kbdlog("ATkbd: set extended controller RAM\n"); - kbd->want60 = 1; - kbd->secr_phase = 1; - return 0; - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - /*Set keyboard controller line P10-P13 (input port bits 0-3) low*/ - if (!PCI || (val > 0xb1)) - kbd->input_port &= ~(1 << (val & 0x03)); - kbd_adddata(0x00); - return 0; - case 0xb4: case 0xb5: - /*Set keyboard controller line P22-P23 (output port bits 2-3) low*/ - if (!PCI) - kbd_output_write(kbd, kbd->output_port & ~(4 << (val & 0x01))); - kbd_adddata(0x00); - return 0; - case 0xb8: case 0xb9: case 0xba: case 0xbb: - /*Set keyboard controller line P10-P13 (input port bits 0-3) high*/ - if (!PCI || (val > 0xb9)) - kbd->input_port |= (1 << (val & 0x03)); - kbd_adddata(0x00); - return 0; - case 0xbc: case 0xbd: - /*Set keyboard controller line P22-P23 (output port bits 2-3) high*/ - if (!PCI) - kbd_output_write(kbd, kbd->output_port | (4 << (val & 0x01))); - kbd_adddata(0x00); - return 0; - case 0xc8: /*AMI - unblock keyboard controller lines P22 and P23 - (allow command D1 to change bits 2 and 3 of the output - port)*/ - kbdlog("AMI - unblock keyboard controller lines P22 and P23\n"); - kbd->output_locked = 1; - return 0; - case 0xc9: /*AMI - block keyboard controller lines P22 and P23 - (prevent command D1 from changing bits 2 and 3 of the - output port)*/ - kbdlog("AMI - block keyboard controller lines P22 and P23\n"); - kbd->output_locked = 1; - return 0; - case 0xca: /*AMI - read keyboard mode*/ - kbdlog("AMI - read keyboard mode\n"); - kbd_adddata(0x00); /*ISA mode*/ - return 0; - case 0xcb: /*AMI - set keyboard mode*/ - kbdlog("AMI - set keyboard mode\n"); - kbd->want60 = 1; - return 0; - case 0xef: /*??? - sent by AMI486*/ - kbdlog("??? - sent by AMI486\n"); - return 0; - } - - return kbd_write64_generic(kbd, val); -} - - -static uint8_t -kbd_write64_ibm_mca(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch (val) { - case 0xc1: /*Copy bits 0 to 3 of input port to status bits 4 to 7*/ - kbdlog("ATkbd: copy bits 0 to 3 of input port to status bits 4 to 7\n"); - kbd->status &= 0xf; - kbd->status |= ((((kbd->input_port & 0xfc) | 0x84 | fdc_ps1_525()) & 0xf) << 4); - return 0; - case 0xc2: /*Copy bits 4 to 7 of input port to status bits 4 to 7*/ - kbdlog("ATkbd: copy bits 4 to 7 of input port to status bits 4 to 7\n"); - kbd->status &= 0xf; - kbd->status |= (((kbd->input_port & 0xfc) | 0x84 | fdc_ps1_525()) & 0xf0); - return 0; - case 0xaf: - kbdlog("ATkbd: bad kbc command AF\n"); - return 1; - case 0xf0: case 0xf1: case 0xf2: case 0xf3: - case 0xf4: case 0xf5: case 0xf6: case 0xf7: - case 0xf8: case 0xf9: case 0xfa: case 0xfb: - case 0xfc: case 0xfd: case 0xfe: case 0xff: - kbdlog("ATkbd: pulse: %01X\n", (val & 0x03) | 0x0c); - kbd_output_pulse(kbd, (val & 0x03) | 0x0c); - return 0; - } - - return kbd_write64_generic(kbd, val); -} - - -static uint8_t -kbd_write60_quadtel(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch(kbd->command) { - case 0xcf: /*??? - sent by MegaPC BIOS*/ - kbdlog("??? - sent by MegaPC BIOS\n"); - return 0; - } - - return 1; -} - - -static uint8_t -kbd_write64_quadtel(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch (val) { - case 0xaf: - kbdlog("ATkbd: bad kbc command AF\n"); - return 1; - case 0xcf: /*??? - sent by MegaPC BIOS*/ - kbdlog("??? - sent by MegaPC BIOS\n"); - kbd->want60 = 1; - return 0; - } - - return kbd_write64_generic(kbd, val); -} - - -static uint8_t -kbd_write60_toshiba(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch(kbd->command) { - case 0xb6: /* T3100e - set colour/mono switch */ - t3100e_mono_set(val); - return 0; - } - - return 1; -} - - -static uint8_t -kbd_write64_toshiba(void *p, uint8_t val) -{ - atkbd_t *kbd = (atkbd_t *) p; - - switch (val) { - case 0xaf: - kbdlog("ATkbd: bad kbc command AF\n"); - return 1; - case 0xb0: /* T3100e: Turbo on */ - t3100e_turbo_set(1); - return 0; - case 0xb1: /* T3100e: Turbo off */ - t3100e_turbo_set(0); - return 0; - case 0xb2: /* T3100e: Select external display */ - t3100e_display_set(0x00); - return 0; - case 0xb3: /* T3100e: Select internal display */ - t3100e_display_set(0x01); - return 0; - case 0xb4: /* T3100e: Get configuration / status */ - kbd_adddata(t3100e_config_get()); - return 0; - case 0xb5: /* T3100e: Get colour / mono byte */ - kbd_adddata(t3100e_mono_get()); - return 0; - case 0xb6: /* T3100e: Set colour / mono byte */ - kbd->want60 = 1; - return 0; - case 0xb7: /* T3100e: Emulate PS/2 keyboard - not implemented */ - case 0xb8: /* T3100e: Emulate AT keyboard - not implemented */ - return 0; - case 0xbb: /* T3100e: Read 'Fn' key. - Return it for right Ctrl and right Alt; on the real - T3100e, these keystrokes could only be generated - using 'Fn'. */ - if (keyboard_recv(0xb8) || /* Right Alt */ - keyboard_recv(0x9d)) /* Right Ctrl */ - kbd_adddata(0x04); - else kbd_adddata(0x00); - return 0; - case 0xbc: /* T3100e: Reset Fn+Key notification */ - t3100e_notify_set(0x00); - return 0; - case 0xc0: /*Read input port*/ - kbdlog("ATkbd: read input port\n"); - - /* The T3100e returns all bits set except bit 6 which - * is set by t3100e_mono_set() */ - kbd->input_port = (t3100e_mono_get() & 1) ? 0xFF : 0xBF; - kbd_adddata(kbd->input_port); - return 0; - - } - - return kbd_write64_generic(kbd, val); -} - - -static void -kbd_write(uint16_t port, uint8_t val, void *priv) -{ - atkbd_t *kbd = (atkbd_t *)priv; - int i = 0; - int bad = 1; - uint8_t mask; - - if (romset == ROM_XI8088 && port == 0x63) - port = 0x61; - - switch (port) { - case 0x60: - if (kbd->want60) { - /*Write to controller*/ - kbd->want60 = 0; - switch (kbd->command) { - case 0x60: case 0x61: case 0x62: case 0x63: - case 0x64: case 0x65: case 0x66: case 0x67: - case 0x68: case 0x69: case 0x6a: case 0x6b: - case 0x6c: case 0x6d: case 0x6e: case 0x6f: - case 0x70: case 0x71: case 0x72: case 0x73: - case 0x74: case 0x75: case 0x76: case 0x77: - case 0x78: case 0x79: case 0x7a: case 0x7b: - case 0x7c: case 0x7d: case 0x7e: case 0x7f: - kbd->mem[kbd->command & 0x1f] = val; - if (kbd->command == 0x60) - kbd_cmd_write(kbd, val); - break; - - case 0xd1: /*Write output port*/ - // kbdlog("Write output port\n"); - if (kbd->output_locked) { - /*If keyboard controller lines P22-P23 are blocked, - we force them to remain unchanged.*/ - val &= ~0x0c; - val |= (kbd->output_port & 0x0c); - } - kbd_output_write(kbd, val); - break; - - case 0xd2: /*Write to keyboard output buffer*/ - kbdlog("ATkbd: write to keyboard output buffer\n"); - kbd_adddata_keyboard(val); - break; - - case 0xd3: /*Write to mouse output buffer*/ - kbdlog("ATkbd: write to mouse output buffer\n"); - if (mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) - keyboard_at_adddata_mouse(val); - break; - - case 0xd4: /*Write to mouse*/ - kbdlog("ATkbd: write to mouse (%02X)\n", val); - kbd_mouse_set(kbd, 1); - if (mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) - mouse_write(val, mouse_p); - else if (!mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) { - pclog("Adding 0xFF to queue\n"); - keyboard_at_adddata_mouse(0xff); - } - break; - - default: - /* Run the vendor-specific command handler, if present, - otherwise (or if the former returns 1), assume bad command. */ - if (kbd->write60_ven) - bad = kbd->write60_ven(kbd, val); - - if (bad) - kbdlog("ATkbd: bad keyboard controller 0060 write %02X command %02X\n", val, kbd->command); - } - } else { - /*Write to keyboard*/ - kbd->mem[0] &= ~0x10; - if (kbd->key_wantdata) { - kbd->key_wantdata = 0; - switch (kbd->key_command) { - case 0xed: /*Set/reset LEDs*/ - kbd_adddata_keyboard(0xfa); - break; - - case 0xf0: /*Get/set scancode set*/ - if (val == 0) { - kbd_adddata_keyboard(keyboard_mode & 3); - } else { - if (val <= 3) { - keyboard_mode &= 0xFC; - keyboard_mode |= (val & 3); - } - kbd_adddata_keyboard(0xfa); - kbd_setmap(kbd); - } - break; - - case 0xf3: /*Set typematic rate/delay*/ - kbd_adddata_keyboard(0xfa); - break; - - default: - kbdlog("ATkbd: bad keyboard 0060 write %02X command %02X\n", val, kbd->key_command); - } - } else { - kbd->key_command = val; - kbd_keyboard_set(kbd, 1); - switch (val) { - case 0x00: - kbdlog("ATkbd: command 00\n"); - kbd_adddata_keyboard(0xfa); - break; - - case 0x05: /*??? - sent by NT 4.0*/ - kbdlog("ATkbd: nt 4.0 command fe\n"); - kbd_adddata_keyboard(0xfe); - break; - - case 0x71: /*These two commands are sent by Pentium-era AMI BIOS'es.*/ - case 0x82: - kbdlog("ATkbd: pentium-era ami bios command %02x\n", val); - break; - - case 0xed: /*Set/reset LEDs*/ - kbdlog("ATkbd: set/reset leds\n"); - kbd->key_wantdata = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xee: /*Diagnostic echo*/ - kbdlog("ATkbd: diagnostic echo\n"); - kbd_adddata_keyboard(0xee); - break; - - case 0xef: /*NOP (No OPeration). Reserved for future use.*/ - kbdlog("ATkbd: kbd nop\n"); - break; - - case 0xf0: /*Get/set scan code set*/ - kbdlog("ATkbd: scan code set\n"); - kbd->key_wantdata = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xf2: /*Read ID*/ - /* Fixed as translation will be done in kbd_adddata_keyboard(). */ - kbdlog("ATkbd: read keyboard id\n"); - kbd_adddata_keyboard(0xfa); - kbd_adddata_keyboard(0xab); - kbd_adddata_keyboard(0x83); - break; - - case 0xf3: /*Set typematic rate/delay*/ - kbdlog("ATkbd: set typematic rate/delay\n"); - kbd->key_wantdata = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xf4: /*Enable keyboard*/ - kbdlog("ATkbd: enable keyboard via keyboard\n"); - keyboard_scan = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xf5: /*Disable keyboard*/ - kbdlog("ATkbd: disable keyboard via keyboard\n"); - keyboard_scan = 0; - kbd_adddata_keyboard(0xfa); - break; - - case 0xf6: /*Set defaults*/ - kbdlog("ATkbd: set defaults\n"); - keyboard_set3_all_break = 0; - keyboard_set3_all_repeat = 0; - memset(keyboard_set3_flags, 0, 512); - keyboard_mode = (keyboard_mode & 0xFC) | 0x02; - kbd_adddata_keyboard(0xfa); - kbd_setmap(kbd); - break; - - case 0xf7: /*Set all keys to repeat*/ - kbdlog("ATkbd: set all keys to repeat\n"); - keyboard_set3_all_break = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xf8: /*Set all keys to give make/break codes*/ - kbdlog("ATkbd: set all keys to give make/break codes\n"); - keyboard_set3_all_break = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xf9: /*Set all keys to give make codes only*/ - kbdlog("ATkbd: set all keys to give make codes only\n"); - keyboard_set3_all_break = 0; - kbd_adddata_keyboard(0xfa); - break; - - case 0xfa: /*Set all keys to repeat and give make/break codes*/ - kbdlog("ATkbd: set all keys to repeat and give make/break codes\n"); - keyboard_set3_all_repeat = 1; - keyboard_set3_all_break = 1; - kbd_adddata_keyboard(0xfa); - break; - - case 0xfe: /*Resend last scan code*/ - kbdlog("ATkbd: reset last scan code\n"); - kbd_adddata_keyboard(kbd->last_scan_code); - break; - - case 0xff: /*Reset*/ - kbdlog("ATkbd: kbd reset\n"); - key_queue_start = key_queue_end = 0; /*Clear key queue*/ - kbd_adddata_keyboard(0xfa); - kbd_adddata_keyboard(0xaa); - /* Set system flag to 1 and scan code set to 2. */ - keyboard_mode &= 0xFC; - keyboard_mode |= 2; - kbd_setmap(kbd); - break; - - default: - kbdlog("ATkbd: bad keyboard command %02X\n", val); - kbd_adddata_keyboard(0xfe); - } - } - } - break; - - case 0x61: - ppi.pb = val; - - timer_process(); - timer_update_outstanding(); - - speaker_update(); - speaker_gated = val & 1; - speaker_enable = val & 2; - if (speaker_enable) - was_speaker_enable = 1; - pit_set_gate(&pit, 2, val & 1); - - if (romset == ROM_XI8088) { - if (val & 0x04) - xi8088_turbo_set(1); - else - xi8088_turbo_set(0); - } - break; - - case 0x64: - kbd->want60 = 0; - kbd->command = val; - /*New controller command*/ - switch (val) { - case 0x20: case 0x21: case 0x22: case 0x23: - case 0x24: case 0x25: case 0x26: case 0x27: - case 0x28: case 0x29: case 0x2a: case 0x2b: - case 0x2c: case 0x2d: case 0x2e: case 0x2f: - case 0x30: case 0x31: case 0x32: case 0x33: - case 0x34: case 0x35: case 0x36: case 0x37: - case 0x38: case 0x39: case 0x3a: case 0x3b: - case 0x3c: case 0x3d: case 0x3e: case 0x3f: - kbd_adddata(kbd->mem[val & 0x1f]); - break; - - case 0x60: case 0x61: case 0x62: case 0x63: - case 0x64: case 0x65: case 0x66: case 0x67: - case 0x68: case 0x69: case 0x6a: case 0x6b: - case 0x6c: case 0x6d: case 0x6e: case 0x6f: - case 0x70: case 0x71: case 0x72: case 0x73: - case 0x74: case 0x75: case 0x76: case 0x77: - case 0x78: case 0x79: case 0x7a: case 0x7b: - case 0x7c: case 0x7d: case 0x7e: case 0x7f: - kbd->want60 = 1; - break; - - case 0xaa: /*Self-test*/ - kbdlog("Self-test\n"); - if ((kbd->flags & KBC_VEN_MASK) == KBC_VEN_TOSHIBA) - kbd->status |= STAT_IFULL; - if (! kbd->initialized) { - kbd->initialized = 1; - key_ctrl_queue_start = key_ctrl_queue_end = 0; - kbd->status &= ~STAT_OFULL; - } - kbd->status |= STAT_SYSFLAG; - kbd->mem[0] |= 0x04; - kbd_keyboard_set(kbd, 1); - if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) - kbd_mouse_set(kbd, 1); - kbd_output_write(kbd, 0xcf); - kbd_adddata(0x55); - break; - - case 0xab: /*Interface test*/ - kbdlog("ATkbd: interface test\n"); - kbd_adddata(0x00); /*no error*/ - break; - - case 0xac: /*Diagnostic dump*/ - kbdlog("ATkbd: diagnostic dump\n"); - for (i=0; i<16; i++) - kbd_adddata(kbd->mem[i]); - kbd_adddata((kbd->input_port & 0xf0) | 0x80); - kbd_adddata(kbd->output_port); - kbd_adddata(kbd->status); - break; - - case 0xad: /*Disable keyboard*/ - kbdlog("ATkbd: disable keyboard\n"); - kbd_keyboard_set(kbd, 0); - break; - - case 0xae: /*Enable keyboard*/ - kbdlog("ATkbd: enable keyboard\n"); - kbd_keyboard_set(kbd, 1); - break; - - case 0xd0: /*Read output port*/ - kbdlog("ATkbd: read output port\n"); - mask = 0xff; - if(!keyboard_scan) - mask &= 0xbf; - if(!mouse_scan && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) - mask &= 0xf7; - kbd_adddata(kbd->output_port & mask); - break; - - case 0xd1: /*Write output port*/ - // kbdlog("ATkbd: write output port\n"); - kbd->want60 = 1; - break; - - case 0xd2: /*Write keyboard output buffer*/ - kbdlog("ATkbd: write keyboard output buffer\n"); - kbd->want60 = 1; - break; - - case 0xdd: /* Disable A20 Address Line */ - kbdlog("ATkbd: disable A20 Address Line\n"); - kbd_output_write(kbd, kbd->output_port & 0xfd); - break; - - case 0xdf: /* Enable A20 Address Line */ - kbdlog("ATkbd: enable A20 address line\n"); - kbd_output_write(kbd, kbd->output_port | 0x02); - break; - - case 0xe0: /*Read test inputs*/ - kbdlog("ATkbd: read test inputs\n"); - kbd_adddata(0x00); - break; - - default: - /* Run the vendor-specific command handler, if present, - otherwise (or if the former returns 1), assume bad command. */ - if (kbd->write64_ven) - bad = kbd->write64_ven(kbd, val); - - if (bad) - kbdlog("ATkbd: bad controller command %02X\n", val); - } - break; - } -} - - -static uint8_t -kbd_read(uint16_t port, void *priv) -{ - atkbd_t *kbd = (atkbd_t *)priv; - uint8_t ret = 0xff; - - if (romset == ROM_XI8088 && port == 0x63) - port = 0x61; - - switch (port) { - case 0x60: - ret = kbd->out; - kbd->status &= ~(STAT_OFULL); - picintc(kbd->last_irq); - kbd->last_irq = 0; - break; - - case 0x61: - ret = ppi.pb & ~0xe0; - if (ppispeakon) - ret |= 0x20; - if ((kbd->flags & KBC_TYPE_MASK) != KBC_TYPE_ISA) { - if (kbd->refresh) - ret |= 0x10; - else - ret &= ~0x10; - } - if (romset == ROM_XI8088){ - if (xi8088_turbo_get()) - ret |= 0x04; - else - ret &= ~0x04; - } - break; - - case 0x64: - ret = (kbd->status & 0xFB) | (keyboard_mode & CCB_SYSTEM); - ret |= STAT_LOCK; - /* The transmit timeout (TTIMEOUT) flag should *NOT* be cleared, otherwise - the IBM PS/2 Model 80's BIOS gives error 8601 (mouse error). */ - kbd->status &= ~(STAT_RTIMEOUT/* | STAT_TTIMEOUT*/); - break; - } - - return(ret); -} - - -static void -kbd_refresh(void *priv) -{ - atkbd_t *kbd = (atkbd_t *)priv; - - kbd->refresh = !kbd->refresh; - kbd->refresh_time += PS2_REFRESH_TIME; -} - - -static void -kbd_reset(void *priv) -{ - atkbd_t *kbd = (atkbd_t *)priv; - - kbd->initialized = 0; - kbd->dtrans = 0; - kbd->first_write = 1; - kbd->status = STAT_LOCK | STAT_CD; - kbd->mem[0] = 0x01; - kbd->wantirq = 0; - kbd_output_write(kbd, 0xcf); - kbd->input_port = (video_is_mda()) ? 0xf0 : 0xb0; - kbd->out_new = -1; - kbd->last_irq = 0; - kbd->secr_phase = 0; - kbd->key_wantdata = 0; - - keyboard_mode = 0x02 | kbd->dtrans; - - kbd_keyboard_set(kbd, 1); - kbd_mouse_set(kbd, 0); - - sc_or = 0; - keyboard_update_states(0, 0, 0); - - memset(keyboard_set3_flags, 0, 512); - - kbd_setmap(kbd); -} - - -static void * -kbd_init(const device_t *info) -{ - atkbd_t *kbd; - - kbd = (atkbd_t *)malloc(sizeof(atkbd_t)); - memset(kbd, 0x00, sizeof(atkbd_t)); - - kbd->flags = info->local; - - kbd_reset(kbd); - - io_sethandler(0x0060, 5, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); - keyboard_send = kbd_adddata_keyboard; - - timer_add(kbd_poll, &keyboard_delay, TIMER_ALWAYS_ENABLED, kbd); - - if ((kbd->flags & KBC_TYPE_MASK) != KBC_TYPE_ISA) { - if ((kbd->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2) - keyboard_mode &= ~0x03; /* These machines force translation off, so the keyboard - must start in scan code set 0. */ - - timer_add(kbd_refresh, - &kbd->refresh_time, TIMER_ALWAYS_ENABLED, kbd); - } - - timer_add(kbd_pulse_poll, - &kbd->pulse_cb, &kbd->pulse_cb, kbd); - - kbd->write60_ven = NULL; - kbd->write64_ven = NULL; - - switch(kbd->flags & KBC_VEN_MASK) { - case KBC_VEN_GENERIC: - kbd->write64_ven = &kbd_write64_generic; - break; - case KBC_VEN_AMI: - kbd->write60_ven = &kbd_write60_ami; - kbd->write64_ven = &kbd_write64_ami; - break; - case KBC_VEN_IBM_MCA: - kbd->write64_ven = &kbd_write64_ibm_mca; - break; - case KBC_VEN_QUADTEL: - kbd->write60_ven = &kbd_write60_quadtel; - kbd->write64_ven = &kbd_write64_quadtel; - break; - case KBC_VEN_TOSHIBA: - kbd->write60_ven = &kbd_write60_toshiba; - kbd->write64_ven = &kbd_write64_toshiba; - break; - } - - /* We need this, sadly. */ - CurrentKbd = kbd; - - return(kbd); -} - - -static void -kbd_close(void *priv) -{ - atkbd_t *kbd = (atkbd_t *)priv; - - kbd_reset(kbd); - - /* Stop timers. */ - keyboard_delay = 0; - kbd->refresh_time = 0; - - keyboard_scan = 0; - keyboard_send = NULL; - - /* Disable the scancode maps. */ - keyboard_set_table(NULL); - - CurrentKbd = NULL; - free(kbd); -} - - -const device_t keyboard_at_device = { - "PC/AT Keyboard", - 0, - KBC_TYPE_ISA | KBC_VEN_GENERIC, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_at_ami_device = { - "PC/AT Keyboard (AMI)", - 0, - KBC_TYPE_ISA | KBC_VEN_AMI, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_at_toshiba_device = { - "PC/AT Keyboard (Toshiba)", - 0, - KBC_TYPE_ISA | KBC_VEN_TOSHIBA, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_device = { - "PS/2 Keyboard", - 0, - KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_ami_device = { - "PS/2 Keyboard (AMI)", - 0, - KBC_TYPE_PS2_1 | KBC_VEN_AMI, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_mca_device = { - "PS/2 Keyboard", - 0, - KBC_TYPE_PS2_1 | KBC_VEN_IBM_MCA, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_mca_2_device = { - "PS/2 Keyboard", - 0, - KBC_TYPE_PS2_2 | KBC_VEN_IBM_MCA, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_quadtel_device = { - "PS/2 Keyboard (Quadtel/MegaPC)", - 0, - KBC_TYPE_PS2_1 | KBC_VEN_QUADTEL, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_pci_device = { - "PS/2 Keyboard", - DEVICE_PCI, - KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - -const device_t keyboard_ps2_ami_pci_device = { - "PS/2 Keyboard (AMI)", - DEVICE_PCI, - KBC_TYPE_PS2_1 | KBC_VEN_AMI, - kbd_init, - kbd_close, - kbd_reset, - NULL, NULL, NULL -}; - - -void -keyboard_at_set_mouse(void (*func)(uint8_t val, void *priv), void *priv) -{ - mouse_write = func; - mouse_p = priv; -} - - -void -keyboard_at_adddata_keyboard_raw(uint8_t val) -{ - key_queue[key_queue_end] = val; - key_queue_end = (key_queue_end + 1) & 0xf; -} - - -void -keyboard_at_adddata_mouse(uint8_t val) -{ - mouse_queue[mouse_queue_end] = val; - mouse_queue_end = (mouse_queue_end + 1) & 0xf; -} - - -void -keyboard_at_set_mouse_scan(uint8_t val) -{ - atkbd_t *kbd = CurrentKbd; - uint8_t temp_mouse_scan = val ? 1 : 0; - - if (temp_mouse_scan == mouse_scan) return; - - kbd_mouse_set(kbd, val ? 1 : 0); - - kbdlog("ATkbd: mouse scan %sabled via PCI\n", mouse_scan ? "en" : "dis"); -} - - -uint8_t -keyboard_at_get_mouse_scan(void) -{ - return(mouse_scan ? 0x10 : 0x00); -} diff --git a/backup code/mouse_bus - Cópia (2).c b/backup code/mouse_bus - Cópia (2).c deleted file mode 100644 index bd626e258..000000000 --- a/backup code/mouse_bus - Cópia (2).c +++ /dev/null @@ -1,876 +0,0 @@ -/* - * 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 Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * This code is based on my Minix driver for the Logitech(-mode) - * interface. Although that driver blindly took IRQ5, the board - * seems to be able to tell the driver what IRQ it is set for. - * When testing on MS-DOS (6.22), the 'mouse.exe' driver did not - * want to start, and only after disassembling it and inspecting - * the code it was discovered that driver actually does use the - * IRQ reporting feature. In a really, really weird way, too: it - * sets up the board, and then reads the CTRL register which is - * supposed to return that IRQ value. Depending on whether or - * not the FREEZE bit is set, it has to return either the two's - * complemented (negated) value, or (if clear) just the value. - * The mouse.com driver reads both values 10,000 times, and - * then makes up its mind. Maybe an effort to 'debounce' the - * reading of the DIP switches? Oh-well. - * - * NOTES: Verified with: - * AMI WinBIOS 486 (5A, no IRQ detect, OK, IRQ5 only) - * Microsoft Mouse.com V2.00 (DOS V6.22, 5A, OK) - * Microsoft Mouse.exe V9.1 (DOS V6.22, A5, OK) - * Logitech LMouse.com V6.02 (DOS V6.22) - * Logitech LMouse.com V6.43 (DOS V6.22) - * Microsoft WfW V3.11 on DOS V6.22 - * GEOS V1.0 (OK, IRQ5 only) - * GEOS V2.0 (OK, IRQ5 only) - * Microsoft Windows 95 OSR2 - * Microsoft Windows 98 SE - * Microsoft Windows NT 3.1 - * Microsoft Windows NT 3.51 - * - * The polling frequency for InPort controllers has to - * be changed to programmable. Microsoft uses 30Hz, - * but ATIXL ports are programmable 30-200Hz. - * - * Based on an early driver for MINIX 1.5. - * - * Version: @(#)mouse_bus.c 1.0.39 2018/05/24 - * - * Authors: Fred N. van Kempen, - * - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" - - -#define MOUSE_PORT 0x023c /* default */ -#define MOUSE_IRQ 5 /* default */ -#define MOUSE_BUTTONS 2 /* default */ -#define MOUSE_DEBUG 0 - - -/* Our mouse device. */ -typedef struct mouse { - const char *name; /* name of this device */ - int8_t type; /* type of this device */ - uint16_t base; /* I/O port base to use */ - int8_t irq; /* IRQ channel to use */ - uint16_t flags; /* device flags */ - - uint8_t r_magic, /* MAGIC register */ - r_ctrl, /* CONTROL register (WR) */ - r_conf, /* CONFIG register */ - r_cmd; /* (MS) current command */ - - uint16_t seq; /* general counter */ - - uint8_t but, /* current mouse status */ - but_last; - uint8_t cur_but; - int8_t x, y; - int x_delay, - y_delay; - uint8_t irq_num; - - int64_t timer; /* mouse event timer */ - - uint8_t (*read)(struct mouse *, uint16_t); - void (*write)(struct mouse *, uint16_t, uint8_t); -} mouse_t; -#define FLAG_NEW 0x100 /* device is the newer variant */ -#define FLAG_INPORT 0x80 /* device is MS InPort */ -#define FLAG_3BTN 0x20 /* enable 3-button mode */ -#define FLAG_SCALED 0x10 /* enable delta scaling */ -#define FLAG_INTR 0x04 /* dev can send interrupts */ -#define FLAG_FROZEN 0x02 /* do not update counters */ -#define FLAG_ENABLED 0x01 /* dev is enabled for use */ - - -/* Definitions for Logitech. */ -#define LTMOUSE_DATA 0 /* DATA register */ -#define LTMOUSE_MAGIC 1 /* signature magic register */ -# define LTMAGIC_BYTE1 0xa5 /* most drivers use this */ -# define LTMAGIC_BYTE2 0x5a /* some drivers use this */ -#define LTMOUSE_CTRL 2 /* CTRL register */ -# define LTCTRL_FREEZE 0x80 /* do not sample when set */ -# define LTCTRL_RD_Y_HI 0x60 -# define LTCTRL_RD_Y_LO 0x40 -# define LTCTRL_RD_X_HI 0x20 -# define LTCTRL_RD_X_LO 0x00 -# define LTCTRL_RD_MASK 0x60 -# define LTCTRL_IDIS 0x10 -# define LTCTRL_IENB 0x00 -#define LTMOUSE_CONFIG 3 /* CONFIG register */ - -/* Definitions for Microsoft. */ -#define MSMOUSE_CTRL 0 /* CTRL register */ -# define MSCTRL_RESET 0x80 /* reset controller */ -# define MSCTRL_FREEZE 0x20 /* HOLD- freeze data */ -# define MSCTRL_IENB_A 0x08 /* ATIXL intr enable */ -# define MSCTRL_IENB_M 0x01 /* MS intr enable */ -# define MSCTRL_COMMAND 0x07 -# define MSCTRL_RD_Y 0x02 -# define MSCTRL_RD_X 0x01 -# define MSCTRL_RD_BUT 0x00 -#define MSMOUSE_DATA 1 /* DATA register */ -# define MSDATA_IRQ 0x16 -# define MSDATA_BASE 0x10 /* MS InPort: 30Hz */ -# define MSDATA_HZ30 0x01 /* ATIXL 30Hz */ -# define MSDATA_HZ50 0x02 /* ATIXL 50Hz */ -# define MSDATA_HZ100 0x03 /* ATIXL 100Hz */ -# define MSDATA_HZ200 0x04 /* ATIXL 200Hz */ -#define MSMOUSE_MAGIC 2 /* MAGIC register */ -# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ -# define MAGIC_MSBYTE2 0x12 -#define MSMOUSE_CONFIG 3 /* CONFIG register */ - - -#ifdef ENABLE_MOUSE_BUS_LOG -int mouse_bus_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -mouse_bus_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (mouse_bus_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Reset the controller state. */ -static void -ms_reset(mouse_t *dev) -{ - dev->r_ctrl = 0x00; - dev->r_cmd = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= (FLAG_INTR | FLAG_ENABLED); - - dev->x_delay = dev->y_delay = 0; - - dev->cur_but = 0x00; -} - - -static void -ms_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - - if (dev->x_delay > 127) { - delta_x = 127; - dev->x_delay -= 127; - } else if (dev->x_delay < -128) { - delta_x = -128; - dev->x_delay += 128; - } else { - delta_x = dev->x_delay; - dev->x_delay = 0; - } - - if (dev->y_delay > 127) { - delta_y = 127; - dev->y_delay -= 127; - } else if (dev->y_delay < -128) { - delta_y = -128; - dev->x_delay += 128; - } else { - delta_y = dev->y_delay; - dev->y_delay = 0; - } - - if (!(dev->flags & FLAG_FROZEN)) { - dev->x = (int8_t) delta_x; - dev->y = (int8_t) delta_y; - dev->cur_but = dev->but; - } -} - - -/* Handle a WRITE to an InPort register. */ -static void -ms_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t valxor; - - switch (port) { - case MSMOUSE_CTRL: - /* Bit 7 is reset. */ - if (val & MSCTRL_RESET) - ms_reset(dev); - - /* Bits 0-2 are the internal register index. */ - switch (val & 0x07) { - case MSCTRL_COMMAND: - case MSCTRL_RD_BUT: - case MSCTRL_RD_X: - case MSCTRL_RD_Y: - dev->r_cmd = val & 0x07; - break; - } - break; - - case MSMOUSE_DATA: - picintc(1 << dev->irq); - - if (val == MSDATA_IRQ) - picint(1 << dev->irq); - else { - switch (dev->r_cmd) { - case MSCTRL_COMMAND: - valxor = (dev->r_ctrl ^ val); - - if (valxor & MSCTRL_FREEZE) { - if (val & MSCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - - dev->x = dev->y = 0; - dev->but = 0; - } - } - - if (val & (MSCTRL_IENB_M | MSCTRL_IENB_A)) - dev->flags |= FLAG_INTR; - else - dev->flags &= ~FLAG_INTR; - - dev->r_ctrl = val; - break; - - default: - break; - } - } - break; - - case MSMOUSE_MAGIC: - break; - - case MSMOUSE_CONFIG: - break; - } -} - - -/* Handle a READ from an InPort register. */ -static uint8_t -ms_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0x00; - - switch (port) { - case MSMOUSE_CTRL: - ret = dev->r_ctrl; - break; - - case MSMOUSE_DATA: - switch (dev->r_cmd) { - case MSCTRL_RD_BUT: - ret = dev->cur_but; - if (dev->flags & FLAG_NEW) - ret |= 0x40; /* On new InPort, always have bit 6 set. */ - break; - - case MSCTRL_RD_X: - ret = dev->x; - break; - - case MSCTRL_RD_Y: - ret = dev->y; - break; - - case MSCTRL_COMMAND: - ret = dev->r_ctrl; - break; - } - break; - - case MSMOUSE_MAGIC: - if (dev->seq & 0x01) - ret = MAGIC_MSBYTE2; - else - ret = MAGIC_MSBYTE1; - dev->seq ^= 1; - break; - - case MSMOUSE_CONFIG: - /* Not really present in real hardware. */ - break; - } - - return(ret); -} - - -/* Reset the controller state. */ -static void -lt_reset(mouse_t *dev) -{ - dev->r_ctrl = (LTCTRL_IDIS) | 0x0f; - dev->r_conf = 0x0e; - dev->r_magic = 0x00; - - dev->seq = 0; - dev->flags &= 0xf0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->irq_num = 0; -} - - -/* Called at 30hz */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev->flags & FLAG_INPORT) { - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - - ms_update_data(dev); - - if (dev->flags & FLAG_INTR) - picint(1 << dev->irq); - } else { - picint(1 << dev->irq); - - if (dev->irq_num == 5) { - mouse_bus_log("5th IRQ, enabling mouse...\n"); - lt_reset(dev); - dev->flags |= FLAG_ENABLED; - } - - if (dev->irq_num == 4) { - mouse_bus_log("4th IRQ, going for the 5th...\n"); - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - } else { - mouse_bus_log("IRQ before the 4th, disabling timer...\n"); - dev->timer = 0; - } - } -} - - -/* Handle a WRITE to a Logitech register. */ -static void -lt_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t b; - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - switch(val) { - case LTMAGIC_BYTE1: - case LTMAGIC_BYTE2: - lt_reset(dev); - dev->r_magic = val; - dev->flags |= FLAG_ENABLED; - break; - } - break; - - case LTMOUSE_CTRL: /* [02] control register */ - if (!(dev->flags & FLAG_ENABLED)) { - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - break; - } - - b = (dev->r_ctrl ^ val); - if (b & LTCTRL_FREEZE) { - if (val & LTCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - dev->x = dev->y = 0; - if (dev->but) - dev->but |= 0x80; - } - } - - if (b & LTCTRL_IDIS) { - /* Disable or enable interrupts. */ - if (val & LTCTRL_IDIS) - dev->flags &= ~FLAG_INTR; - else - dev->flags |= FLAG_INTR; - } - - /* Save new register value. */ - dev->r_ctrl = val | 0x0F; - - /* Clear any pending interrupts. */ - picintc(1 << dev->irq); - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - /* - * The original Logitech design was based on using a - * 8255 parallel I/O chip. This chip has to be set up - * for proper operation, and this configuration data - * is what is programmed into this register. - * - * A snippet of code found in the FreeBSD kernel source - * explains the value: - * - * D7 = Mode set flag (1 = active) - * D6,D5 = Mode selection (port A) - * 00 = Mode 0 = Basic I/O - * 01 = Mode 1 = Strobed I/O - * 10 = Mode 2 = Bi-dir bus - * D4 = Port A direction (1 = input) - * D3 = Port C (upper 4 bits) direction. (1 = input) - * D2 = Mode selection (port B & C) - * 0 = Mode 0 = Basic I/O - * 1 = Mode 1 = Strobed I/O - * D1 = Port B direction (1 = input) - * D0 = Port C (lower 4 bits) direction. (1 = input) - * - * So 91 means Basic I/O on all 3 ports, Port A is an input - * port, B is an output port, C is split with upper 4 bits - * being an output port and lower 4 bits an input port, and - * enable the sucker. Courtesy Intel 8255 databook. Lars - */ - dev->r_conf = val; - break; - - default: - break; - } -} - - -static int -lt_read_int(mouse_t *dev) -{ - if (!(dev->flags & FLAG_NEW)) - return 1; /* On old LogiBus, read the IRQ bits always. */ - - if (dev->flags & FLAG_INTR) - return 1; /* On new LogiBus, read the IRQ bits if interrupts are enabled. */ - - return 0; /* Otherwise, do not. */ -} - - -/* Handle a READ from a Logitech register. */ -static uint8_t -lt_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0xff; - - /* The GEOS drivers actually check this. */ - if (! (dev->flags & FLAG_ENABLED)) return(ret); - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - ret = 0x07; - if (dev->but & 0x01) /* LEFT */ - ret &= ~0x04; - if (dev->but & 0x02) /* RIGHT */ - ret &= ~0x01; - if (dev->flags & FLAG_3BTN) - if (dev->but & 0x04) /* MIDDLE */ - ret &= ~0x02; - ret <<= 5; - - switch(dev->r_ctrl & LTCTRL_RD_MASK) { - case LTCTRL_RD_X_LO: /* X, low bits */ - ret |= (dev->x & 0x0f); - break; - - case LTCTRL_RD_X_HI: /* X, high bits */ - ret |= (dev->x >> 4) & 0x0f; - break; - - case LTCTRL_RD_Y_LO: /* Y, low bits */ - ret |= (dev->y & 0x0f); - break; - - case LTCTRL_RD_Y_HI: /* Y, high bits */ - ret |= (dev->y >> 4) & 0x0f; - break; - } - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - /* - * Drivers write a magic byte to this register, usually - * this is either 5A (AMI WinBIOS, MS Mouse 2.0) or - * A5 (MS Mouse 9.1, Windows drivers, UNIX/Linux/Minix.) - */ - ret = dev->r_magic; - break; - -0x20 >> 5 = 0x01 -0x20 >> 4 = 0x02 -0x20 >> 3 = 0x04 -0x20 >> 2 = 0x08 - - case LTMOUSE_CTRL: /* [02] control register */ - ret = dev->r_ctrl; - dev->r_ctrl |= 0x0F; - if ((dev->seq > 0x3FF) && lt_read_int(dev)) { - /* !IDIS, return DIP switch setting. */ - dev->r_ctrl &= ~((1 << 5) >> dev->irq); -#if 0 - switch(dev->irq) { - case 2: - dev->r_ctrl &= ~0x08; - break; - - case 3: - dev->r_ctrl &= ~0x04; - break; - - case 4: - dev->r_ctrl &= ~0x02; - break; - - case 5: - dev->r_ctrl &= ~0x01; - break; - } -#endif - } - dev->seq = (dev->seq + 1) & 0x7ff; - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - ret = dev->r_conf; - break; - - default: - break; - } - - return(ret); -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -bm_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - mouse_bus_log("%s: write(%d,%02x)\n", dev->name, port & 0x03, val); - - dev->write(dev, port & 0x03, val); -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -bm_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t ret; - - ret = dev->read(dev, port & 0x03); - - mouse_bus_log("%s: read(%d): %02x\n", dev->name, port & 0x03, ret); - - return(ret); -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - uint8_t b_last; - mouse_t *dev = (mouse_t *)priv; - - b_last = dev->but; - - /* Return early if nothing to do. */ - if (!x && !y && !z && (dev->but == b)) - return(1); - - /* If we are not enabled, return. */ - if (! (dev->flags & FLAG_ENABLED)) - mouse_bus_log("bm_poll(): Mouse not enabled\n"); - - if (dev->flags & FLAG_SCALED) { - /* Scale down the motion. */ - if ((x < -1) || (x > 1)) x >>= 1; - if ((y < -1) || (y > 1)) y >>= 1; - } - - if (dev->flags & FLAG_INPORT) { - if (x || y || z) - dev->but = 0x40; /* Mouse has moved. */ - else - dev->but = 0x00; - - if (x > 127) x = 127; - if (y > 127) y = 127; - if (x < -128) x = -128; - if (y < -128) y = -128; - - dev->x_delay += x; - dev->y_delay += y; - dev->but |= (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->flags & FLAG_3BTN) - dev->but |= ((b & 4) >> 1); - - if ((b_last ^ dev->but) & 0x04) - dev->but |= 0x20; /* Left button state has changed. */ - if (((b_last ^ dev->but) & 0x02) && (dev->flags & FLAG_3BTN)) - dev->but |= 0x10; /* Middle button state has changed. */ - if ((b_last ^ dev->but) & 0x01) - dev->but |= 0x08; /* Right button state has changed. */ - - dev->but |= 0x80; /* Packet complete. */ - } else { - /* If we are frozen, do not update the state. */ - if (! (dev->flags & FLAG_FROZEN)) { - /* Add the delta to our state. */ - x += dev->x; - if (x > 127) - x = 127; - if (x < -128) - x = -128; - dev->x = (int8_t)x; - - y += dev->y; - if (y > 127) - y = 127; - if (y < -1287) - y = -1287; - dev->y = (int8_t)y; - - dev->x_delay += x; - dev->y_delay += y; - - dev->but = b; - } - - /* Either way, generate an interrupt. */ - if ((dev->flags & FLAG_INTR) && !(dev->flags & FLAG_INPORT)) - picint(1 << dev->irq); - } - - return(0); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Release our I/O range. */ - io_removehandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - int i, j; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - dev->type = info->local; - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_3BTN; - j = device_get_config_int("model"); - if (j) - dev->flags |= FLAG_NEW; - - switch(dev->type) { - case MOUSE_TYPE_LOGIBUS: - lt_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = lt_read; - dev->write = lt_write; - - dev->timer = 0; - timer_add(bm_timer, &dev->timer, &dev->timer, dev); - break; - - case MOUSE_TYPE_INPORT: - dev->flags |= FLAG_INPORT; - ms_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = ms_read; - dev->write = ms_write; - - dev->timer = (33334LL * TIMER_USEC); - timer_add(bm_timer, &dev->timer, TIMER_ALWAYS_ENABLED, dev); - break; - } - - /* Request an I/O range. */ - io_sethandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - mouse_bus_log("%s: I/O=%04x, IRQ=%d, buttons=%d, model=%s\n", - dev->name, dev->base, dev->irq, i, j ? "new" : "old"); - - /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); - - /* Return our private data to the I/O layer. */ - return(dev); -} - - -static const device_config_t bm_config[] = { - { - "base", "Address", CONFIG_HEX16, "", MOUSE_PORT, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", MOUSE_IRQ, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", MOUSE_BUTTONS, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "model", "Model", CONFIG_SELECTION, "", 0, { - { - "Old", 0 - }, - { - "New", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; diff --git a/backup code/mouse_bus - Cópia (3).c b/backup code/mouse_bus - Cópia (3).c deleted file mode 100644 index 424d75b53..000000000 --- a/backup code/mouse_bus - Cópia (3).c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * 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 Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * NOTES: Ported from Bochs with extensive modifications per testing - * of the real hardware, testing of drivers, and the old code. - * - * Logitech Bus Mouse verified with: - * Logitech LMouse.com 3.12 - * Logitech LMouse.com 3.30 - * Logitech LMouse.com 3.41 - * Logitech LMouse.com 3.42 - * Logitech LMouse.com 4.00 - * Logitech LMouse.com 5.00 - * Logitech LMouse.com 6.00 - * Logitech LMouse.com 6.02 Beta - * Logitech LMouse.com 6.02 - * Logitech LMouse.com 6.12 - * Logitech LMouse.com 6.20 - * Logitech LMouse.com 6.23 - * Logitech LMouse.com 6.30 - * Logitech LMouse.com 6.31E - * Logitech LMouse.com 6.34 - * Logitech Mouse.exe 6.40 - * Logitech Mouse.exe 6.41 - * Logitech Mouse.exe 6.44 - * Logitech Mouse.exe 6.46 - * Logitech Mouse.exe 6.50 - * Microsoft Mouse.com 2.00 - * Microsoft Mouse.sys 3.00 - * Microsoft Windows 1.00 DR5 - * Microsoft Windows 3.10.026 - * Microsoft Windows NT 3.1 - * Microsoft Windows 95 - * - * InPort verified with: - * Logitech LMouse.com 6.12 - * Logitech LMouse.com 6.41 - * Microsoft Windows NT 3.1 - * Microsoft Windows 98 SE - * - * Version: @(#)mouse_bus.c 1.0.0 2018/05/23 - * - * Authors: Miran Grca, - * - * Copyright 200?-2018 Bochs. - * Copyright 2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" - -#define IRQ_MASK ((1<<5) >> dev->irq) - -/* MS Inport Bus Mouse Adapter */ -#define INP_PORT_CONTROL 0x0000 -#define INP_PORT_DATA 0x0001 -#define INP_PORT_SIGNATURE 0x0002 -#define INP_PORT_CONFIG 0x0003 - -#define INP_CTRL_READ_BUTTONS 0x00 -#define INP_CTRL_READ_X 0x01 -#define INP_CTRL_READ_Y 0x02 -#define INP_CTRL_COMMAND 0x07 -#define INP_CTRL_RAISE_IRQ 0x16 -#define INP_CTRL_RESET 0x80 - -#define INP_HOLD_COUNTER (1 << 5) -#define INP_ENABLE_TIMER_IRQ (1 << 4) -#define INP_ENABLE_DATA_IRQ (1 << 3) -#define INP_PERIOD_MASK 0x07 - -#define INP_PERIOD (33334LL * TIMER_USEC) - -/* MS/Logictech Standard Bus Mouse Adapter */ -#define BUSM_PORT_DATA 0x0000 -#define BUSM_PORT_SIGNATURE 0x0001 -#define BUSM_PORT_CONTROL 0x0002 -#define BUSM_PORT_CONFIG 0x0003 - -/* The MS/Logitech Standard Bus Mouse sends data about 45 times a second */ -#define BUSM_PERIOD (22223LL * TIMER_USEC) - -#define HOLD_COUNTER (1 << 7) -#define READ_X (0 << 6) -#define READ_Y (1 << 6) -#define READ_LOW (0 << 5) -#define READ_HIGH (1 << 5) -#define DISABLE_IRQ (1 << 4) - -#define READ_X_LOW (READ_X | READ_LOW) -#define READ_X_HIGH (READ_X | READ_HIGH) -#define READ_Y_LOW (READ_Y | READ_LOW) -#define READ_Y_HIGH (READ_Y | READ_HIGH) - - -/* Our mouse device. */ -typedef struct mouse { - int type, model, base, irq, bn, - mouse_delayed_dx, mouse_delayed_dy, - mouse_buttons, - current_x, current_y, - current_b, - control_val, mouse_buttons_last, - config_val, sig_val, - command_val, toggle_counter, - data_int, hold, - interrupts; - - double period; - - int64_t timer_enabled, timer; /* mouse event timer */ -} mouse_t; - - -#ifdef ENABLE_MOUSE_BUS_LOG -int bm_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -bm_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (bm_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -bm_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t value; - - if (dev->type == MOUSE_TYPE_INPORT) { - switch (port & 0x03) { - case INP_PORT_CONTROL: - value = dev->control_val; - break; - case INP_PORT_DATA: - switch (dev->command_val) { - case INP_CTRL_READ_BUTTONS: - value = dev->current_b | 0x80; - if (dev->model) - value |= 0x40; /* Newer Logitech mouse drivers look for bit 6 set */ - break; - case INP_CTRL_READ_X: - value = dev->current_x; - break; - case INP_CTRL_READ_Y: - value = dev->current_y; - break; - case INP_CTRL_COMMAND: - value = dev->control_val; - break; - default: - bm_log("ERROR: Reading data port in unsupported mode 0x%02x\n", dev->control_val); - } - break; - case INP_PORT_SIGNATURE: - if (dev->toggle_counter) - value = 0x12; - else - value = 0xDE; - dev->toggle_counter ^= 1; - break; - case INP_PORT_CONFIG: - bm_log("ERROR: Unsupported read from port 0x%04x\n", port); - break; - } - } else { - switch (port & 0x03) { - case BUSM_PORT_CONTROL: - value = dev->control_val; - dev->control_val |= 0x0F; - - if ((dev->toggle_counter > 0x3FF) && (!dev->model || dev->interrupts)) - dev->control_val &= ~IRQ_MASK; - dev->toggle_counter = (dev->toggle_counter + 1) & 0x7FF; - break; - case BUSM_PORT_DATA: - /* Testing and another source confirm that the buttons are - *ALWAYS* present, so I'm going to change this a bit. */ - switch (dev->control_val & 0x60) { - case READ_X_LOW: - value = dev->current_x & 0x0F; - break; - case READ_X_HIGH: - value = (dev->current_x >> 4) & 0x0F; - break; - case READ_Y_LOW: - value = dev->current_y & 0x0F; - break; - case READ_Y_HIGH: - value = (dev->current_y >> 4) & 0x0F; - break; - default: - bm_log("ERROR: Reading data port in unsupported mode 0x%02x\n", dev->control_val); - } - value |= ((dev->current_b ^ 7) << 5); - break; - case BUSM_PORT_CONFIG: - value = dev->config_val; - break; - case BUSM_PORT_SIGNATURE: - value = dev->sig_val; - break; - } - } - - bm_log("DEBUG: read from address 0x%04x, value = 0x%02x\n", port, value); - - return value; -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -bm_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - bm_log("DEBUG: write to address 0x%04x, value = 0x%02x\n", port, val); - - if (dev->type == MOUSE_TYPE_INPORT) { - switch (port & 0x03) { - case INP_PORT_CONTROL: - /* Bit 7 is reset. */ - if (val & INP_CTRL_RESET) - dev->control_val = 0; - - /* Bits 0-2 are the internal register index. */ - switch(val & 0x07) { - case INP_CTRL_COMMAND: - case INP_CTRL_READ_BUTTONS: - case INP_CTRL_READ_X: - case INP_CTRL_READ_Y: - dev->command_val = val & 0x07; - break; - default: - bm_log("ERROR: Unsupported command written to port 0x%04x (value = 0x%02x)\n", port, val); - } - break; - case INP_PORT_DATA: - picintc(1 << dev->irq); - switch(dev->command_val) { - case INP_CTRL_COMMAND: - dev->hold = (val & INP_HOLD_COUNTER) > 0; - - dev->interrupts = (val & INP_ENABLE_TIMER_IRQ) > 0; - dev->data_int = (val & INP_ENABLE_DATA_IRQ) > 0; - - switch(val & INP_PERIOD_MASK) { - case 0: - dev->period = 0.0; - dev->timer_enabled = 0; - break; - case 1: - dev->period = 1000000.0 / 30.0; - dev->timer_enabled = (val & INP_ENABLE_TIMER_IRQ) ? *TIMER_ALWAYS_ENABLED : 0; - break; - case 2: - dev->period = 1000000.0 / 50.0; - dev->timer_enabled = (val & INP_ENABLE_TIMER_IRQ) ? *TIMER_ALWAYS_ENABLED : 0; - break; - case 3: - dev->period = 1000000.0 / 100.0; - dev->timer_enabled = (val & INP_ENABLE_TIMER_IRQ) ? *TIMER_ALWAYS_ENABLED : 0; - break; - case 4: - dev->period = 1000000.0 / 200.0; - dev->timer_enabled = (val & INP_ENABLE_TIMER_IRQ) ? *TIMER_ALWAYS_ENABLED : 0; - break; - case 6: - if (val & INP_ENABLE_TIMER_IRQ) - picint(1 << dev->irq); - dev->control_val &= INP_PERIOD_MASK; - dev->control_val |= (val & ~INP_PERIOD_MASK); - return; - default: - bm_log("ERROR: Unsupported period written to port 0x%04x (value = 0x%02x)\n", port, val); - } - - dev->control_val = val; - - break; - default: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - } - break; - case INP_PORT_SIGNATURE: - case INP_PORT_CONFIG: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - break; - } - } else { - switch (port & 0x03) { - case BUSM_PORT_CONTROL: - dev->control_val = val | 0x0F; - - dev->interrupts = (val & DISABLE_IRQ) == 0; - dev->hold = (val & HOLD_COUNTER) > 0; - - picintc(1 << dev->irq); - - break; - case BUSM_PORT_CONFIG: - dev->config_val = val; - break; - case BUSM_PORT_SIGNATURE: - dev->sig_val = val; - break; - case BUSM_PORT_DATA: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - break; - } - } -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t shift = 0xff; - - if (dev->type == MOUSE_TYPE_INPORT) - shift = 0x07; - - if (!x && !y && !((b ^ dev->mouse_buttons_last) & shift)/* && (dev->type == MOUSE_TYPE_INPORT)*/) - return(1); /* State has not changed, do nothing. */ - - /* change button staste MRL to LMR */ - dev->mouse_buttons = (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->bn == 3) - dev->mouse_buttons |= ((b & 4) >> 1); - - if (dev->type == MOUSE_TYPE_INPORT) { - /* InPort mouse. */ - - /* If the mouse has moved, set bit 6. */ - if (x || y) - dev->mouse_buttons |= 0x40; - - /* Set bits 3-5 according to button state changes. */ - if ((b ^ dev->mouse_buttons_last) & (1 << 0)) - dev->mouse_buttons |= (1 << 5); - if ((b ^ dev->mouse_buttons_last) & (1 << 4) && (dev->bn == 3)) - dev->mouse_buttons |= (1 << 4); - if ((b ^ dev->mouse_buttons_last) & (1 << 2)) - dev->mouse_buttons |= (1 << 3); - } - - dev->mouse_buttons_last = b; - - /* Clamp x and y to between -128 and 127 (int8_t range). */ - if (x > 127) x = 127; - if (x < -128) x = -128; - - if (y > 127) y = 127; - if (y < -128) y = -128; - - if (dev->timer_enabled) { /* Timer interrupt mode. */ - /* Update delayed coordinates. */ - dev->mouse_delayed_dx += x; - dev->mouse_delayed_dy += y; - } else { /* Data interrupt mode. */ - /* If the counters are not frozen, update them. */ - if (!dev->hold) { - dev->current_x = (int8_t) x; - dev->current_y = (int8_t) y; - - dev->current_b = dev->mouse_buttons; - } - - /* Send interrupt. */ - if (dev->data_int) { - picintc(1 << dev->irq); - picint(1 << dev->irq); - bm_log("DEBUG: Data Interrupt Fired...\n"); - } - } - return(0); -} - - -static void -bm_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - - if (dev->mouse_delayed_dx > 127) { - delta_x = 127; - dev->mouse_delayed_dx -= 127; - } else if (dev->mouse_delayed_dx < -128) { - delta_x = -128; - dev->mouse_delayed_dx += 128; - } else { - delta_x = dev->mouse_delayed_dx; - dev->mouse_delayed_dx = 0; - } - - if (dev->mouse_delayed_dy > 127) { - delta_y = 127; - dev->mouse_delayed_dy -= 127; - } else if (dev->mouse_delayed_dy < -128) { - delta_y = -128; - dev->mouse_delayed_dy += 128; - } else { - delta_y = dev->mouse_delayed_dy; - dev->mouse_delayed_dy = 0; - } - - if (!dev->hold) { - dev->current_x = (uint8_t) delta_x; - dev->current_y = (uint8_t) delta_y; - dev->current_b = dev->mouse_buttons; - } -} - - -/* Called at 30hz */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev->type == MOUSE_TYPE_INPORT) - dev->timer = ((int64_t) dev->period) * TIMER_USEC; - else - dev->timer = BUSM_PERIOD; - - if (dev->interrupts) { - picintc(1 << dev->irq); - picint(1 << dev->irq); - bm_log("DEBUG: Timer Interrupt Fired...\n"); - } - - bm_update_data(dev); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev) - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - - dev->type = info->local; - dev->model = device_get_config_int("model"); - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - dev->bn = device_get_config_int("buttons"); - mouse_set_buttons(dev->bn); - - io_sethandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - dev->mouse_delayed_dx = 0; - dev->mouse_delayed_dy = 0; - dev->mouse_buttons = 0; - dev->current_x = - dev->current_y = - dev->current_b = 0; - - if (dev->type == MOUSE_TYPE_INPORT) { - dev->control_val = 0; /* the control port value */ - dev->mouse_buttons_last = 0; - dev->period = 0.0; /* 30 Hz default */ - dev->timer = 0LL; - dev->timer_enabled = 0; - } else { - dev->control_val = 0x0f; /* the control port value */ - dev->config_val = 0x0e; /* the config port value */ - dev->sig_val = 0; /* the signature port value */ - dev->timer = BUSM_PERIOD; - dev->timer_enabled = *TIMER_ALWAYS_ENABLED; - dev->interrupts = 1; - } - dev->data_int = 0; - dev->interrupts = 0; /* timer interrupts off */ - dev->command_val = 0; /* command byte */ - dev->toggle_counter = 0; /* signature byte / IRQ bit toggle */ - dev->hold = 0; /* counter freeze */ - - timer_add(bm_timer, &dev->timer, &dev->timer_enabled, dev); - - if (dev->type == MOUSE_TYPE_INPORT) - bm_log("MS Inport BusMouse initialized\n"); - else - bm_log("Standard MS/Logitech BusMouse initialized\n"); - - return dev; -} - - -static const device_config_t bm_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x23c, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "model", "Model", CONFIG_SELECTION, "", 0, { - { - "Old", 0 - }, - { - "New", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; diff --git a/backup code/mouse_bus - Cópia (4).c b/backup code/mouse_bus - Cópia (4).c deleted file mode 100644 index ad2f53bed..000000000 --- a/backup code/mouse_bus - Cópia (4).c +++ /dev/null @@ -1,805 +0,0 @@ -/* - * 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 Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * NOTES: Ported from Bochs with extensive modifications per testing - * of the real hardware, testing of drivers, and the old code. - * - * Logitech Bus Mouse verified with: - * Logitech LMouse.com 3.12 - * Logitech LMouse.com 3.30 - * Logitech LMouse.com 3.41 - * Logitech LMouse.com 3.42 - * Logitech LMouse.com 4.00 - * Logitech LMouse.com 5.00 - * Logitech LMouse.com 6.00 - * Logitech LMouse.com 6.02 Beta - * Logitech LMouse.com 6.02 - * Logitech LMouse.com 6.12 - * Logitech LMouse.com 6.20 - * Logitech LMouse.com 6.23 - * Logitech LMouse.com 6.30 - * Logitech LMouse.com 6.31E - * Logitech LMouse.com 6.34 - * Logitech Mouse.exe 6.40 - * Logitech Mouse.exe 6.41 - * Logitech Mouse.exe 6.44 - * Logitech Mouse.exe 6.46 - * Logitech Mouse.exe 6.50 - * Microsoft Mouse.com 2.00 - * Microsoft Mouse.sys 3.00 - * Microsoft Windows 1.00 DR5 - * Microsoft Windows 3.10.026 - * Microsoft Windows NT 3.1 - * Microsoft Windows 95 - * - * InPort verified with: - * Logitech LMouse.com 6.12 - * Logitech LMouse.com 6.41 - * Microsoft Windows NT 3.1 - * Microsoft Windows 98 SE - * - * Version: @(#)mouse_bus.c 1.0.0 2018/05/23 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 200?-2018 Bochs. - * Copyright 2017,2018 Miran Grca. - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" -#if 1 -#include "random.h" -#endif - -#define IRQ_MASK ((1 << 5) >> dev->irq) - -/* MS Inport Bus Mouse Adapter */ -#define INP_PORT_CONTROL 0x0000 -#define INP_PORT_DATA 0x0001 -#define INP_PORT_SIGNATURE 0x0002 -#define INP_PORT_CONFIG 0x0003 - -#define INP_CTRL_READ_BUTTONS 0x00 -#define INP_CTRL_READ_X 0x01 -#define INP_CTRL_READ_Y 0x02 -#define INP_CTRL_COMMAND 0x07 -#define INP_CTRL_RAISE_IRQ 0x16 -#define INP_CTRL_RESET 0x80 - -#define INP_HOLD_COUNTER (1 << 5) -#define INP_ENABLE_TIMER_IRQ (1 << 4) -#define INP_ENABLE_DATA_IRQ (1 << 3) -#define INP_PERIOD_MASK 0x07 - -/* MS/Logictech Standard Bus Mouse Adapter */ -#define BUSM_PORT_DATA 0x0000 -#define BUSM_PORT_SIGNATURE 0x0001 -#define BUSM_PORT_CONTROL 0x0002 -#define BUSM_PORT_CONFIG 0x0003 - -#define HOLD_COUNTER (1 << 7) -#define READ_X (0 << 6) -#define READ_Y (1 << 6) -#define READ_LOW (0 << 5) -#define READ_HIGH (1 << 5) -#define DISABLE_IRQ (1 << 4) - -#define DEVICE_ACTIVE (1 << 7) - -#define READ_X_LOW (READ_X | READ_LOW) -#define READ_X_HIGH (READ_X | READ_HIGH) -#define READ_Y_LOW (READ_Y | READ_LOW) -#define READ_Y_HIGH (READ_Y | READ_HIGH) - -#define FLAG_INPORT (1 << 0) -#define FLAG_NEW (1 << 1) -#define FLAG_ENABLED (1 << 2) -#define FLAG_HOLD (1 << 3) -#define FLAG_TIMER_INT (1 << 4) -#define FLAG_DATA_INT (1 << 5) - -static const double periods[4] = { 30.0, 50.0, 100.0, 200.0 }; - - -/* Our mouse device. */ -typedef struct mouse { - int base, irq, bn, flags, - mouse_delayed_dx, mouse_delayed_dy, - mouse_buttons, - current_x, current_y, - current_b, - control_val, mouse_buttons_last, - config_val, sig_val, - command_val, toggle_counter; - - double period; - - int64_t timer_enabled, timer; /* mouse event timer */ -} mouse_t; - - -#ifdef ENABLE_MOUSE_BUS_LOG -int bm_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -bm_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (bm_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -lt_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t value; - - switch (port & 0x03) { - case BUSM_PORT_DATA: - /* Testing and another source confirm that the buttons are - *ALWAYS* present, so I'm going to change this a bit. */ - switch (dev->control_val & 0x60) { - case READ_X_LOW: - value = dev->current_x & 0x0F; - break; - case READ_X_HIGH: - value = (dev->current_x >> 4) & 0x0F; - break; - case READ_Y_LOW: - value = dev->current_y & 0x0F; - break; - case READ_Y_HIGH: - value = (dev->current_y >> 4) & 0x0F; - break; - default: - bm_log("ERROR: Reading data port in unsupported mode 0x%02x\n", dev->control_val); - } - value |= ((dev->current_b ^ 7) << 5); - break; - case BUSM_PORT_SIGNATURE: - value = dev->sig_val; - break; - case BUSM_PORT_CONTROL: - value = dev->control_val; - dev->control_val |= 0x0F; - - /* If the conditions are right, simulate the flakiness of the correct IRQ bit. */ - if (!(dev->flags & FLAG_NEW) || (dev->flags & FLAG_TIMER_INT)) - dev->control_val = (dev->control_val & ~IRQ_MASK) | (random_generate() & IRQ_MASK); - break; - case BUSM_PORT_CONFIG: - /* Read from config port returns control_val in the upper 4 bits when enabled, - possibly solid interrupt readout in the lower 4 bits, 0xff when not (at power-up). */ - if (dev->flags & FLAG_ENABLED) - return (dev->control_val | 0x0F) & ~IRQ_MASK; - else - return 0xff; - break; - } - - bm_log("DEBUG: read from address 0x%04x, value = 0x%02x\n", port, value); - - return value; -} - - -static uint8_t -ms_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t value; - - switch (port & 0x03) { - case INP_PORT_CONTROL: - value = dev->control_val; - break; - case INP_PORT_DATA: - switch (dev->command_val) { - case INP_CTRL_READ_BUTTONS: - value = dev->current_b | 0x80; - break; - case INP_CTRL_READ_X: - value = dev->current_x; - break; - case INP_CTRL_READ_Y: - value = dev->current_y; - break; - case INP_CTRL_COMMAND: - value = dev->control_val; - break; - default: - bm_log("ERROR: Reading data port in unsupported mode 0x%02x\n", dev->control_val); - } - break; - case INP_PORT_SIGNATURE: - if (dev->toggle_counter) - value = 0x12; - else - value = 0xDE; - dev->toggle_counter ^= 1; - break; - case INP_PORT_CONFIG: - bm_log("ERROR: Unsupported read from port 0x%04x\n", port); - break; - } - - bm_log("DEBUG: read from address 0x%04x, value = 0x%02x\n", port, value); - - return value; -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -lt_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - bm_log("DEBUG: write to address 0x%04x, value = 0x%02x\n", port, val); - - switch (port & 0x03) { - case BUSM_PORT_DATA: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - break; - case BUSM_PORT_SIGNATURE: - dev->sig_val = val; - break; - case BUSM_PORT_CONTROL: - dev->control_val = val | 0x0F; - - if (!(val & DISABLE_IRQ)) - dev->flags |= FLAG_TIMER_INT; - else - dev->flags &= ~FLAG_TIMER_INT; - - if (val & HOLD_COUNTER) - dev->flags |= FLAG_HOLD; - else - dev->flags &= ~FLAG_HOLD; - - picintc(1 << dev->irq); - - break; - case BUSM_PORT_CONFIG: - /* - * The original Logitech design was based on using a - * 8255 parallel I/O chip. This chip has to be set up - * for proper operation, and this configuration data - * is what is programmed into this register. - * - * A snippet of code found in the FreeBSD kernel source - * explains the value: - * - * D7 = Mode set flag (1 = active) - * D6,D5 = Mode selection (port A) - * 00 = Mode 0 = Basic I/O - * 01 = Mode 1 = Strobed I/O - * 10 = Mode 2 = Bi-dir bus - * D4 = Port A direction (1 = input) - * D3 = Port C (upper 4 bits) direction. (1 = input) - * D2 = Mode selection (port B & C) - * 0 = Mode 0 = Basic I/O - * 1 = Mode 1 = Strobed I/O - * D1 = Port B direction (1 = input) - * D0 = Port C (lower 4 bits) direction. (1 = input) - * - * So 91 means Basic I/O on all 3 ports, Port A is an input - * port, B is an output port, C is split with upper 4 bits - * being an output port and lower 4 bits an input port, and - * enable the sucker. Courtesy Intel 8255 databook. Lars - */ - dev->config_val = val; - if (val & DEVICE_ACTIVE) { - dev->flags |= FLAG_ENABLED; - dev->control_val = 0x0F & ~IRQ_MASK; - } else - dev->flags &= ~FLAG_ENABLED; - break; - } -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -ms_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - bm_log("DEBUG: write to address 0x%04x, value = 0x%02x\n", port, val); - - switch (port & 0x03) { - case INP_PORT_CONTROL: - /* Bit 7 is reset. */ - if (val & INP_CTRL_RESET) - dev->control_val = 0; - - /* Bits 0-2 are the internal register index. */ - switch(val & 0x07) { - case INP_CTRL_COMMAND: - case INP_CTRL_READ_BUTTONS: - case INP_CTRL_READ_X: - case INP_CTRL_READ_Y: - dev->command_val = val & 0x07; - break; - default: - bm_log("ERROR: Unsupported command written to port 0x%04x (value = 0x%02x)\n", port, val); - } - break; - case INP_PORT_DATA: - picintc(1 << dev->irq); - switch(dev->command_val) { - case INP_CTRL_COMMAND: - if (val & INP_HOLD_COUNTER) - dev->flags |= FLAG_HOLD; - else - dev->flags &= ~FLAG_HOLD; - - if (val & INP_ENABLE_TIMER_IRQ) - dev->flags |= FLAG_TIMER_INT; - else - dev->flags &= ~FLAG_TIMER_INT; - - if (val & INP_ENABLE_DATA_IRQ) - dev->flags |= FLAG_DATA_INT; - else - dev->flags &= ~FLAG_DATA_INT; - - switch(val & INP_PERIOD_MASK) { - case 0: - dev->period = 0.0; - dev->timer = 0LL; - dev->timer_enabled = 0LL; - break; - - case 1: - case 2: - case 3: - case 4: - dev->period = 1000000.0 / periods[(val & INP_PERIOD_MASK) - 1]; - dev->timer = ((int64_t) dev->period) * TIMER_USEC; - dev->timer_enabled = (val & INP_ENABLE_TIMER_IRQ) ? 1LL : 0LL; - bm_log("DEBUG: Timer is now %sabled at period %i\n", (val & INP_ENABLE_TIMER_IRQ) ? "en" : "dis", (int32_t) dev->period); - break; - - case 6: - if (val & INP_ENABLE_TIMER_IRQ) - picint(1 << dev->irq); - dev->control_val &= INP_PERIOD_MASK; - dev->control_val |= (val & ~INP_PERIOD_MASK); - return; - default: - bm_log("ERROR: Unsupported period written to port 0x%04x (value = 0x%02x)\n", port, val); - } - - dev->control_val = val; - - break; - default: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - } - break; - case INP_PORT_SIGNATURE: - case INP_PORT_CONFIG: - bm_log("ERROR: Unsupported write to port 0x%04x (value = 0x%02x)\n", port, val); - break; - } -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - int xor; - - if (!(dev->flags & FLAG_ENABLED)) - return(1); /* Mouse is disabled, do nothing. */ - - if (!x && !y && !((b ^ dev->mouse_buttons_last) & 0x07)) { - dev->mouse_buttons_last = b; - return(1); /* State has not changed, do nothing. */ - } - - /* Converts button states from MRL to LMR. */ - dev->mouse_buttons = (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->bn == 3) - dev->mouse_buttons |= ((b & 4) >> 1); - - if ((dev->flags & FLAG_INPORT) && !dev->timer_enabled) { - /* This is an InPort mouse in data interrupt mode, - so update bits 6-3 here. */ - - /* If the mouse has moved, set bit 6. */ - if (x || y) - dev->mouse_buttons |= 0x40; - - /* Set bits 3-5 according to button state changes. */ - xor = ((dev->current_b ^ dev->mouse_buttons) & 0x07) << 3; - dev->mouse_buttons |= xor; - } - - dev->mouse_buttons_last = b; - - /* Clamp x and y to between -128 and 127 (int8_t range). */ - if (x > 127) x = 127; - if (x < -128) x = -128; - - if (y > 127) y = 127; - if (y < -128) y = -128; - - if (dev->timer_enabled) { - /* Update delayed coordinates. */ - dev->mouse_delayed_dx += x; - dev->mouse_delayed_dy += y; - } else { - /* If the counters are not frozen, update them. */ - if (!(dev->flags & FLAG_HOLD)) { - dev->current_x = (int8_t) x; - dev->current_y = (int8_t) y; - - dev->current_b = dev->mouse_buttons; - } - - /* Send interrupt. */ - if (dev->flags & FLAG_DATA_INT) { - picint(1 << dev->irq); - bm_log("DEBUG: Data Interrupt Fired...\n"); - } - } - return(0); -} - - -/* The timer calls us on every tick if the mouse is in timer mode - (InPort mouse is so configured, MS/Logitech Bus mouse always). */ -static void -bm_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - int xor; - - /* Update the deltas and the delays. */ - if (dev->mouse_delayed_dx > 127) { - delta_x = 127; - dev->mouse_delayed_dx -= 127; - } else if (dev->mouse_delayed_dx < -128) { - delta_x = -128; - dev->mouse_delayed_dx += 128; - } else { - delta_x = dev->mouse_delayed_dx; - dev->mouse_delayed_dx = 0; - } - - if (dev->mouse_delayed_dy > 127) { - delta_y = 127; - dev->mouse_delayed_dy -= 127; - } else if (dev->mouse_delayed_dy < -128) { - delta_y = -128; - dev->mouse_delayed_dy += 128; - } else { - delta_y = dev->mouse_delayed_dy; - dev->mouse_delayed_dy = 0; - } - - /* If the counters are not frozen, update them. */ - if (!(dev->flags & FLAG_HOLD)) { - dev->current_x = (uint8_t) delta_x; - dev->current_y = (uint8_t) delta_y; - } - - if (dev->flags & FLAG_INPORT) { - /* This is an InPort mouse in timer mode, so update current_b always, - and update bits 6-3 (mouse moved and button state changed) here. */ - xor = ((dev->current_b ^ dev->mouse_buttons) & 0x07) << 3; - dev->current_b = (dev->mouse_buttons & 0x87) | xor; - if (delta_x || delta_y) - dev->current_b |= 0x40; - } else if (!(dev->flags & FLAG_HOLD)) { - /* This is a MS/Logitech Bus Mouse, so only update current_b if the - counters are frozen. */ - dev->current_b = dev->mouse_buttons; - } -} - - -/* Called at the configured period (InPort mouse) or 45 times per second (MS/Logitech Bus mouse). */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - bm_log("DEBUG: Timer Tick (flags=%08X)...\n", dev->flags); - - /* The period is configured either via emulator settings (for MS/Logitech Bus mouse) - or via software (for InPort mouse). */ - dev->timer += ((int64_t) dev->period) * TIMER_USEC; - - if (dev->flags & FLAG_TIMER_INT) { - picint(1 << dev->irq); - bm_log("DEBUG: Timer Interrupt Fired...\n"); - } - - bm_update_data(dev); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev) - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - - if (info->local == MOUSE_TYPE_INPORT) - dev->flags = FLAG_INPORT; - else - dev->flags = 0; - - if (device_get_config_int("model")) - dev->flags |= FLAG_NEW; - - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - dev->bn = device_get_config_int("buttons"); - mouse_set_buttons(dev->bn); - - dev->mouse_delayed_dx = 0; - dev->mouse_delayed_dy = 0; - dev->mouse_buttons = 0; - dev->mouse_buttons_last = 0; - dev->sig_val = 0; /* the signature port value */ - dev->current_x = - dev->current_y = - dev->current_b = 0; - dev->command_val = 0; /* command byte */ - dev->toggle_counter = 0; /* signature byte / IRQ bit toggle */ - - if (dev->flags & FLAG_INPORT) { - dev->control_val = 0; /* the control port value */ - dev->timer = 0LL; - dev->timer_enabled = 0; - dev->flags |= FLAG_ENABLED; - dev->period = 0.0; - - io_sethandler(dev->base, 4, - ms_read, NULL, NULL, ms_write, NULL, NULL, dev); - } else { - dev->control_val = 0x0f; /* the control port value */ - dev->config_val = 0x0e; /* the config port value */ - dev->period = 1000000.0 / ((double) device_get_config_int("hz")); - dev->timer = ((int64_t) dev->period) * TIMER_USEC; - dev->timer_enabled = 1LL; - dev->flags |= FLAG_TIMER_INT; - - io_sethandler(dev->base, 4, - lt_read, NULL, NULL, lt_write, NULL, NULL, dev); - } - - timer_add(bm_timer, &dev->timer, &dev->timer_enabled, dev); - - if (dev->flags & FLAG_INPORT) - bm_log("MS Inport BusMouse initialized\n"); - else - bm_log("Standard MS/Logitech BusMouse initialized\n"); - - return dev; -} - - -static const device_config_t lt_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x23c, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "hz", "Hz", CONFIG_SELECTION, "", 30, { - { - "30 Hz (JMP2 = 1)", 30 - }, - { - "45 Hz (JMP2 not populated)", 45 - }, - { - "60 Hz (JMP 2 = 2)", 60 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "model", "Model", CONFIG_SELECTION, "", 0, { - { - "Old", 0 - }, - { - "New", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -static const device_config_t ms_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x23c, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 5, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", 2, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - lt_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - ms_config -}; diff --git a/backup code/mouse_bus - Cópia 2.c b/backup code/mouse_bus - Cópia 2.c deleted file mode 100644 index f2fd8ab99..000000000 --- a/backup code/mouse_bus - Cópia 2.c +++ /dev/null @@ -1,877 +0,0 @@ -/* - * 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 Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * This code is based on my Minix driver for the Logitech(-mode) - * interface. Although that driver blindly took IRQ5, the board - * seems to be able to tell the driver what IRQ it is set for. - * When testing on MS-DOS (6.22), the 'mouse.exe' driver did not - * want to start, and only after disassembling it and inspecting - * the code it was discovered that driver actually does use the - * IRQ reporting feature. In a really, really weird way, too: it - * sets up the board, and then reads the CTRL register which is - * supposed to return that IRQ value. Depending on whether or - * not the FREEZE bit is set, it has to return either the two's - * complemented (negated) value, or (if clear) just the value. - * The mouse.com driver reads both values 10,000 times, and - * then makes up its mind. Maybe an effort to 'debounce' the - * reading of the DIP switches? Oh-well. - * - * NOTES: Verified with: - * AMI WinBIOS 486 (5A, no IRQ detect, OK, IRQ5 only) - * Microsoft Mouse.com V2.00 (DOS V6.22, 5A, OK) - * Microsoft Mouse.exe V9.1 (DOS V6.22, A5, OK) - * Logitech LMouse.com V6.02 (DOS V6.22) - * Logitech LMouse.com V6.43 (DOS V6.22) - * Microsoft WfW V3.11 on DOS V6.22 - * GEOS V1.0 (OK, IRQ5 only) - * GEOS V2.0 (OK, IRQ5 only) - * Microsoft Windows 95 OSR2 - * Microsoft Windows 98 SE - * Microsoft Windows NT 3.1 - * Microsoft Windows NT 3.51 - * - * The polling frequency for InPort controllers has to - * be changed to programmable. Microsoft uses 30Hz, - * but ATIXL ports are programmable 30-200Hz. - * - * Based on an early driver for MINIX 1.5. - * - * Version: @(#)mouse_bus.c 1.0.37 2018/05/22 - * - * Authors: Fred N. van Kempen, - * - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" - - -#define MOUSE_PORT 0x023c /* default */ -#define MOUSE_IRQ 5 /* default */ -#define MOUSE_BUTTONS 2 /* default */ -#define MOUSE_DEBUG 0 - - -/* Our mouse device. */ -typedef struct mouse { - const char *name; /* name of this device */ - int8_t type; /* type of this device */ - uint16_t base; /* I/O base to use */ - int8_t irq; /* IRQ channel to use */ - uint16_t flags; /* device flags */ - - uint8_t r_magic, /* MAGIC register */ - r_ctrl, /* CONTROL register (WR) */ - r_conf, /* CONFIG register */ - r_cmd; /* (MS) current command */ - - uint8_t seq; /* general counter */ - - uint8_t but, /* current mouse status */ - but_last; - uint8_t cur_but; - int8_t x, y; - int x_delay, - y_delay; - uint8_t irq_num; - - int64_t timer; /* mouse event timer */ - - uint8_t (*read)(struct mouse *, uint16_t); - void (*write)(struct mouse *, uint16_t, uint8_t); -} mouse_t; -#define FLAG_NEW 0x100 /* device is the newer variant */ -#define FLAG_INPORT 0x80 /* device is MS InPort */ -#define FLAG_3BTN 0x20 /* enable 3-button mode */ -#define FLAG_SCALED 0x10 /* enable delta scaling */ -#define FLAG_INTR 0x04 /* dev can send interrupts */ -#define FLAG_FROZEN 0x02 /* do not update counters */ -#define FLAG_ENABLED 0x01 /* dev is enabled for use */ - - -/* Definitions for Logitech. */ -#define LTMOUSE_DATA 0 /* DATA register */ -#define LTMOUSE_MAGIC 1 /* signature magic register */ -# define LTMAGIC_BYTE1 0xa5 /* most drivers use this */ -# define LTMAGIC_BYTE2 0x5a /* some drivers use this */ -#define LTMOUSE_CTRL 2 /* CTRL register */ -# define LTCTRL_FREEZE 0x80 /* do not sample when set */ -# define LTCTRL_RD_Y_HI 0x60 -# define LTCTRL_RD_Y_LO 0x40 -# define LTCTRL_RD_X_HI 0x20 -# define LTCTRL_RD_X_LO 0x00 -# define LTCTRL_RD_MASK 0x60 -# define LTCTRL_IDIS 0x10 -# define LTCTRL_IENB 0x00 -#define LTMOUSE_CONFIG 3 /* CONFIG register */ - -/* Definitions for Microsoft. */ -#define MSMOUSE_CTRL 0 /* CTRL register */ -# define MSCTRL_RESET 0x80 /* reset controller */ -# define MSCTRL_FREEZE 0x20 /* HOLD- freeze data */ -# define MSCTRL_IENB_A 0x08 /* ATIXL intr enable */ -# define MSCTRL_IENB_M 0x01 /* MS intr enable */ -# define MSCTRL_COMMAND 0x07 -# define MSCTRL_RD_Y 0x02 -# define MSCTRL_RD_X 0x01 -# define MSCTRL_RD_BUT 0x00 -#define MSMOUSE_DATA 1 /* DATA register */ -# define MSDATA_IRQ 0x16 -# define MSDATA_BASE 0x10 /* MS InPort: 30Hz */ -# define MSDATA_HZ30 0x01 /* ATIXL 30Hz */ -# define MSDATA_HZ50 0x02 /* ATIXL 50Hz */ -# define MSDATA_HZ100 0x03 /* ATIXL 100Hz */ -# define MSDATA_HZ200 0x04 /* ATIXL 200Hz */ -#define MSMOUSE_MAGIC 2 /* MAGIC register */ -# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ -# define MAGIC_MSBYTE2 0x12 -#define MSMOUSE_CONFIG 3 /* CONFIG register */ - - -#define ENABLE_MOUSE_BUS_LOG 1 -#ifdef ENABLE_MOUSE_BUS_LOG -int mouse_bus_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -mouse_bus_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (mouse_bus_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Reset the controller state. */ -static void -ms_reset(mouse_t *dev) -{ - dev->r_ctrl = 0x00; - dev->r_cmd = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= (FLAG_INTR | FLAG_ENABLED); - - dev->x_delay = dev->y_delay = 0; - - dev->cur_but = 0x00; -} - - -static void -ms_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - - if (dev->x_delay > 127) { - delta_x = 127; - dev->x_delay -= 127; - } else if (dev->x_delay < -128) { - delta_x = -128; - dev->x_delay += 128; - } else { - delta_x = dev->x_delay; - dev->x_delay = 0; - } - - if (dev->y_delay > 127) { - delta_y = 127; - dev->y_delay -= 127; - } else if (dev->y_delay < -128) { - delta_y = -128; - dev->x_delay += 128; - } else { - delta_y = dev->y_delay; - dev->y_delay = 0; - } - - if (!(dev->flags & FLAG_FROZEN)) { - dev->x = (int8_t) delta_x; - dev->y = (int8_t) delta_y; - dev->cur_but = dev->but; - } -} - - -/* Handle a WRITE to an InPort register. */ -static void -ms_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t valxor; - - switch (port) { - case MSMOUSE_CTRL: - /* Bit 7 is reset. */ - /* Bits 0-2 are the internal register index. */ - switch (val) { - case MSCTRL_RESET: - // ms_reset(dev); - dev->r_ctrl = 0x00; - dev->r_cmd = 0x00; - break; - case MSCTRL_COMMAND: - case MSCTRL_RD_BUT: - case MSCTRL_RD_X: - case MSCTRL_RD_Y: - dev->r_cmd = val; - break; - case 0x87: - // ms_reset(dev); - dev->r_ctrl = 0x00; - dev->r_cmd = 0x07; - break; - } - break; - - case MSMOUSE_DATA: - picintc(1 << dev->irq); - - if (val == MSDATA_IRQ) - picint(1 << dev->irq); - else { - switch (dev->r_cmd) { - case MSCTRL_COMMAND: - valxor = (dev->r_ctrl ^ val); - - if (valxor & MSCTRL_FREEZE) { - if (val & MSCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - - /* dev->x = dev->y = 0; - dev->but = 0; */ - } - } - - if (val & (MSCTRL_IENB_M | MSCTRL_IENB_A)) - dev->flags |= FLAG_INTR; - else - dev->flags &= ~FLAG_INTR; - - dev->r_ctrl = val; - break; - - default: - break; - } - } - break; - - case MSMOUSE_MAGIC: - break; - - case MSMOUSE_CONFIG: - break; - } -} - - -/* Handle a READ from an InPort register. */ -static uint8_t -ms_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0x00; - - switch (port) { - case MSMOUSE_CTRL: - ret = dev->r_ctrl; - break; - - case MSMOUSE_DATA: - switch (dev->r_cmd) { - case MSCTRL_RD_BUT: - ret = dev->cur_but; - if (dev->flags & FLAG_NEW) - ret |= 0x40; /* On new InPort, always have bit 6 set. */ - break; - - case MSCTRL_RD_X: - ret = dev->x; - break; - - case MSCTRL_RD_Y: - ret = dev->y; - break; - - case MSCTRL_COMMAND: - ret = dev->r_ctrl; - break; - } - break; - - case MSMOUSE_MAGIC: - if (dev->seq & 0x01) - ret = MAGIC_MSBYTE2; - else - ret = MAGIC_MSBYTE1; - dev->seq ^= 1; - break; - - case MSMOUSE_CONFIG: - /* Not really present in real hardware. */ - break; - } - - return(ret); -} - - -/* Reset the controller state. */ -static void -lt_reset(mouse_t *dev) -{ - dev->r_magic = 0x00; - dev->r_ctrl = (LTCTRL_IENB); - dev->r_conf = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= FLAG_INTR; - - dev->irq_num = 0; -} - - -/* Called at 30hz */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev->flags & FLAG_INPORT) { - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - - ms_update_data(dev); - - if (dev->flags & FLAG_INTR) - picint(1 << dev->irq); - } else { - picint(1 << dev->irq); - - if (dev->irq_num == 5) { - mouse_bus_log("5th IRQ, enabling mouse...\n"); - lt_reset(dev); - dev->flags |= FLAG_ENABLED; - } - - if (dev->irq_num == 4) { - mouse_bus_log("4th IRQ, going for the 5th...\n"); - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - } else { - mouse_bus_log("IRQ before the 4th, disabling timer...\n"); - dev->timer = 0; - } - } -} - - -/* Handle a WRITE to a Logitech register. */ -static void -lt_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t b; - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - switch(val) { - case LTMAGIC_BYTE1: - case LTMAGIC_BYTE2: - lt_reset(dev); - dev->r_magic = val; - dev->flags |= FLAG_ENABLED; - break; - } - break; - - case LTMOUSE_CTRL: /* [02] control register */ - if (!(dev->flags & FLAG_ENABLED)) { - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - break; - } - - b = (dev->r_ctrl ^ val); - if (b & LTCTRL_FREEZE) { - if (val & LTCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - dev->x = dev->y = 0; - if (dev->but) - dev->but |= 0x80; - } - } - - if (b & LTCTRL_IDIS) { - /* Disable or enable interrupts. */ - if (val & LTCTRL_IDIS) - dev->flags &= ~FLAG_INTR; - else - dev->flags |= FLAG_INTR; - } - - /* Save new register value. */ - dev->r_ctrl = val; - - /* Clear any pending interrupts. */ - picintc(1 << dev->irq); - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - /* - * The original Logitech design was based on using a - * 8255 parallel I/O chip. This chip has to be set up - * for proper operation, and this configuration data - * is what is programmed into this register. - * - * A snippet of code found in the FreeBSD kernel source - * explains the value: - * - * D7 = Mode set flag (1 = active) - * D6,D5 = Mode selection (port A) - * 00 = Mode 0 = Basic I/O - * 01 = Mode 1 = Strobed I/O - * 10 = Mode 2 = Bi-dir bus - * D4 = Port A direction (1 = input) - * D3 = Port C (upper 4 bits) direction. (1 = input) - * D2 = Mode selection (port B & C) - * 0 = Mode 0 = Basic I/O - * 1 = Mode 1 = Strobed I/O - * D1 = Port B direction (1 = input) - * D0 = Port C (lower 4 bits) direction. (1 = input) - * - * So 91 means Basic I/O on all 3 ports, Port A is an input - * port, B is an output port, C is split with upper 4 bits - * being an output port and lower 4 bits an input port, and - * enable the sucker. Courtesy Intel 8255 databook. Lars - */ - dev->r_conf = val; - break; - - default: - break; - } -} - - -static int -lt_read_int(mouse_t *dev) -{ - if (!(dev->flags & FLAG_NEW)) - return 1; /* On old LogiBus, read the IRQ bits always. */ - - if (dev->flags & FLAG_INTR) - return 1; /* On new LogiBus, read the IRQ bits if interrupts are enabled. */ - - return 0; /* Otherwise, do not. */ -} - - -/* Handle a READ from a Logitech register. */ -static uint8_t -lt_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0xff; - - /* The GEOS drivers actually check this. */ - if (! (dev->flags & FLAG_ENABLED)) return(ret); - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - ret = 0x07; - if (dev->but & 0x01) /* LEFT */ - ret &= ~0x04; - if (dev->but & 0x02) /* RIGHT */ - ret &= ~0x01; - if (dev->flags & FLAG_3BTN) - if (dev->but & 0x04) /* MIDDLE */ - ret &= ~0x02; - ret <<= 5; - - switch(dev->r_ctrl & LTCTRL_RD_MASK) { - case LTCTRL_RD_X_LO: /* X, low bits */ - ret |= (dev->x & 0x0f); - break; - - case LTCTRL_RD_X_HI: /* X, high bits */ - ret |= (dev->x >> 4) & 0x0f; - break; - - case LTCTRL_RD_Y_LO: /* Y, low bits */ - ret |= (dev->y & 0x0f); - break; - - case LTCTRL_RD_Y_HI: /* Y, high bits */ - ret |= (dev->y >> 4) & 0x0f; - break; - } - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - /* - * Drivers write a magic byte to this register, usually - * this is either 5A (AMI WinBIOS, MS Mouse 2.0) or - * A5 (MS Mouse 9.1, Windows drivers, UNIX/Linux/Minix.) - */ - ret = dev->r_magic; - break; - - case LTMOUSE_CTRL: /* [02] control register */ - ret = 0x0f; - if (!(dev->r_ctrl & LTCTRL_IDIS) && (dev->seq > 0x3FF) && lt_read_int(dev)) { - /* !IDIS, return DIP switch setting. */ - switch(dev->irq) { - case 2: - ret &= ~0x08; - break; - - case 3: - ret &= ~0x04; - break; - - case 4: - ret &= ~0x02; - break; - - case 5: - ret &= ~0x01; - break; - } - } - dev->seq = (dev->seq + 1) & 0x7ff; - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - ret = dev->r_conf; - break; - - default: - break; - } - - return(ret); -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -bm_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - mouse_bus_log("%s: write(%d,%02x)\n", dev->name, port & 0x03, val); - - dev->write(dev, port & 0x03, val); -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -bm_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t ret; - - ret = dev->read(dev, port & 0x03); - - mouse_bus_log("%s: read(%d): %02x\n", dev->name, port & 0x03, ret); - - return(ret); -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - uint8_t b_last; - mouse_t *dev = (mouse_t *)priv; - - b_last = dev->but; - - /* Return early if nothing to do. */ - if (!x && !y && !z && (dev->but == b)) - return(1); - - /* If we are not enabled, return. */ - if (! (dev->flags & FLAG_ENABLED)) - mouse_bus_log("bm_poll(): Mouse not enabled\n"); - - if (dev->flags & FLAG_SCALED) { - /* Scale down the motion. */ - if ((x < -1) || (x > 1)) x >>= 1; - if ((y < -1) || (y > 1)) y >>= 1; - } - - if (dev->flags & FLAG_INPORT) { - if (x || y || z) - dev->but = 0x40; /* Mouse has moved. */ - else - dev->but = 0x00; - - if (x > 127) x = 127; - if (y > 127) y = 127; - if (x < -128) x = -128; - if (y < -128) y = -128; - - dev->x_delay += x; - dev->y_delay += y; - dev->but |= (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->flags & FLAG_3BTN) - dev->but |= ((b & 4) >> 1); - - if ((b_last ^ dev->but) & 0x04) - dev->but |= 0x20; /* Left button state has changed. */ - if (((b_last ^ dev->but) & 0x02) && (dev->flags & FLAG_3BTN)) - dev->but |= 0x10; /* Middle button state has changed. */ - if ((b_last ^ dev->but) & 0x01) - dev->but |= 0x08; /* Right button state has changed. */ - - dev->but |= 0x80; /* Packet complete. */ - } else { - /* If we are frozen, do not update the state. */ - if (! (dev->flags & FLAG_FROZEN)) { - /* Add the delta to our state. */ - x += dev->x; - if (x > 127) - x = 127; - if (x < -128) - x = -128; - dev->x = (int8_t)x; - - y += dev->y; - if (y > 127) - y = 127; - if (y < -1287) - y = -1287; - dev->y = (int8_t)y; - - dev->x_delay += x; - dev->y_delay += y; - - dev->but = b; - } - - /* Either way, generate an interrupt. */ - if ((dev->flags & FLAG_INTR) && !(dev->flags & FLAG_INPORT)) - picint(1 << dev->irq); - } - - return(0); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Release our I/O range. */ - io_removehandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - int i, j; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - dev->type = info->local; - dev->irq = device_get_config_int("irq"); - dev->base = device_get_config_hex16("base"); - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_3BTN; - j = device_get_config_int("model"); - if (j) - dev->flags |= FLAG_NEW; - - switch(dev->type) { - case MOUSE_TYPE_LOGIBUS: - lt_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = lt_read; - dev->write = lt_write; - - dev->timer = 0; - timer_add(bm_timer, &dev->timer, &dev->timer, dev); - break; - - case MOUSE_TYPE_INPORT: - dev->flags |= FLAG_INPORT; - ms_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = ms_read; - dev->write = ms_write; - - dev->timer = (33334LL * TIMER_USEC); - timer_add(bm_timer, &dev->timer, TIMER_ALWAYS_ENABLED, dev); - break; - } - - /* Request an I/O range. */ - io_sethandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - mouse_bus_log("%s: I/O=%04x, IRQ=%d, buttons=%d, model=%s\n", - dev->name, dev->base, dev->irq, i, j ? "new" : "old"); - - /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); - - /* Return our private data to the I/O layer. */ - return(dev); -} - - -static const device_config_t bm_config[] = { - { - "base", "Address", CONFIG_HEX16, "", MOUSE_PORT, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", MOUSE_IRQ, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", MOUSE_BUTTONS, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "model", "Model", CONFIG_SELECTION, "", 0, { - { - "Old", 0 - }, - { - "New", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; diff --git a/backup code/mouse_bus - Cópia.c b/backup code/mouse_bus - Cópia.c deleted file mode 100644 index f13bcfd37..000000000 --- a/backup code/mouse_bus - Cópia.c +++ /dev/null @@ -1,794 +0,0 @@ -/* - * 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 Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * This code is based on my Minix driver for the Logitech(-mode) - * interface. Although that driver blindly took IRQ5, the board - * seems to be able to tell the driver what IRQ it is set for. - * When testing on MS-DOS (6.22), the 'mouse.exe' driver did not - * want to start, and only after disassembling it and inspecting - * the code it was discovered that driver actually does use the - * IRQ reporting feature. In a really, really weird way, too: it - * sets up the board, and then reads the CTRL register which is - * supposed to return that IRQ value. Depending on whether or - * not the FREEZE bit is set, it has to return either the two's - * complemented (negated) value, or (if clear) just the value. - * The mouse.com driver reads both values 10,000 times, and - * then makes up its mind. Maybe an effort to 'debounce' the - * reading of the DIP switches? Oh-well. - * - * NOTES: Verified with: - * AMI WinBIOS 486 (5A, no IRQ detect, OK, IRQ5 only) - * Microsoft Mouse.com V2.00 (DOS V6.22, 5A, OK) - * Microsoft Mouse.exe V9.1 (DOS V6.22, A5, OK) - * Logitech LMouse.com V6.02 (DOS V6.22) - * Logitech LMouse.com V6.43 (DOS V6.22) - * Microsoft WfW V3.11 on DOS V6.22 - * GEOS V1.0 (OK, IRQ5 only) - * GEOS V2.0 (OK, IRQ5 only) - * Microsoft Windows 95 OSR2 - * Microsoft Windows 98 SE - * Microsoft Windows NT 3.1 - * Microsoft Windows NT 3.51 - * - * The polling frequency for InPort controllers has to - * be changed to programmable. Microsoft uses 30Hz, - * but ATIXL ports are programmable 30-200Hz. - * - * Based on an early driver for MINIX 1.5. - * - * Version: @(#)mouse_bus.c 1.0.34 2018/04/29 - * - * Authors: Fred N. van Kempen, - * - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" - - -#define MOUSE_PORT 0x023c /* default */ -#define MOUSE_IRQ 5 /* default */ -#define MOUSE_BUTTONS 2 /* default */ -#define MOUSE_DEBUG 0 - - -/* Our mouse device. */ -typedef struct mouse { - const char *name; /* name of this device */ - int8_t type; /* type of this device */ - int8_t irq; /* IRQ channel to use */ - uint8_t flags; /* device flags */ - - uint8_t r_magic, /* MAGIC register */ - r_ctrl, /* CONTROL register (WR) */ - r_conf, /* CONFIG register */ - r_cmd; /* (MS) current command */ - - uint8_t seq; /* general counter */ - - uint8_t but, /* current mouse status */ - but_last; - uint8_t cur_but; - int8_t x, y; - int x_delay, - y_delay; - uint8_t need_upd; - uint8_t irq_num; - - int64_t timer; /* mouse event timer */ - - uint8_t (*read)(struct mouse *, uint16_t); - void (*write)(struct mouse *, uint16_t, uint8_t); -} mouse_t; -#define FLAG_INPORT 0x80 /* device is MS InPort */ -#define FLAG_3BTN 0x20 /* enable 3-button mode */ -#define FLAG_SCALED 0x10 /* enable delta scaling */ -#define FLAG_INTR 0x04 /* dev can send interrupts */ -#define FLAG_FROZEN 0x02 /* do not update counters */ -#define FLAG_ENABLED 0x01 /* dev is enabled for use */ - - -/* Definitions for Logitech. */ -#define LTMOUSE_DATA 0 /* DATA register */ -#define LTMOUSE_MAGIC 1 /* signature magic register */ -# define LTMAGIC_BYTE1 0xa5 /* most drivers use this */ -# define LTMAGIC_BYTE2 0x5a /* some drivers use this */ -#define LTMOUSE_CTRL 2 /* CTRL register */ -# define LTCTRL_FREEZE 0x80 /* do not sample when set */ -# define LTCTRL_RD_Y_HI 0x60 -# define LTCTRL_RD_Y_LO 0x40 -# define LTCTRL_RD_X_HI 0x20 -# define LTCTRL_RD_X_LO 0x00 -# define LTCTRL_RD_MASK 0x60 -# define LTCTRL_IDIS 0x10 -# define LTCTRL_IENB 0x00 -#define LTMOUSE_CONFIG 3 /* CONFIG register */ - -/* Definitions for Microsoft. */ -#define MSMOUSE_CTRL 0 /* CTRL register */ -# define MSCTRL_RESET 0x80 /* reset controller */ -# define MSCTRL_FREEZE 0x20 /* HOLD- freeze data */ -# define MSCTRL_IENB_A 0x08 /* ATIXL intr enable */ -# define MSCTRL_IENB_M 0x01 /* MS intr enable */ -# define MSCTRL_COMMAND 0x07 -# define MSCTRL_RD_Y 0x02 -# define MSCTRL_RD_X 0x01 -# define MSCTRL_RD_BUT 0x00 -#define MSMOUSE_DATA 1 /* DATA register */ -# define MSDATA_IRQ 0x16 -# define MSDATA_BASE 0x10 /* MS InPort: 30Hz */ -# define MSDATA_HZ30 0x01 /* ATIXL 30Hz */ -# define MSDATA_HZ50 0x02 /* ATIXL 50Hz */ -# define MSDATA_HZ100 0x03 /* ATIXL 100Hz */ -# define MSDATA_HZ200 0x04 /* ATIXL 200Hz */ -#define MSMOUSE_MAGIC 2 /* MAGIC register */ -# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ -// # define MAGIC_MSBYTE2 0x12 -# define MAGIC_MSBYTE2 0x22 /* According to the Bochs code, this sould be 0x22, not 0x12. */ -#define MSMOUSE_CONFIG 3 /* CONFIG register */ - - -#ifdef ENABLE_MOUSE_BUS_LOG -int mouse_bus_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -mouse_bus_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (mouse_bus_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Reset the controller state. */ -static void -ms_reset(mouse_t *dev) -{ - dev->r_ctrl = 0x00; - dev->r_cmd = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= (FLAG_INTR | FLAG_ENABLED); - - dev->x_delay = dev->y_delay = 0; - dev->need_upd = 0; - - dev->cur_but = 0x00; -} - - -static void -ms_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - - if (dev->x_delay > 127) { - delta_x = 127; - dev->x_delay -= 127; - } else if (dev->x_delay < -128) { - delta_x = -128; - dev->x_delay += 128; - } else { - delta_x = dev->x_delay; - dev->x_delay = 0; - } - - if (dev->y_delay > 127) { - delta_y = 127; - dev->y_delay -= 127; - } else if (dev->y_delay < -128) { - delta_y = -128; - dev->x_delay += 128; - } else { - delta_y = dev->y_delay; - dev->y_delay = 0; - } - - if ((dev->x_delay == 0) && (dev->y_delay == 0)) - dev->need_upd = 0; - - dev->x = (int8_t) delta_x; - dev->y = (int8_t) delta_y; - dev->cur_but = dev->but; -} - - -/* Handle a WRITE to an InPort register. */ -static void -ms_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - switch (port) { - case MSMOUSE_CTRL: - switch (val) { - case MSCTRL_RESET: - ms_reset(dev); - break; - - case MSCTRL_COMMAND: - case MSCTRL_RD_BUT: - case MSCTRL_RD_X: - case MSCTRL_RD_Y: - dev->r_ctrl = val & 0x07; - break; - - case 0x87: - ms_reset(dev); - dev->r_ctrl = MSCTRL_COMMAND; - break; - } - break; - - case MSMOUSE_DATA: - picintc(1 << dev->irq); - if (val == MSDATA_IRQ) { - picint(1<irq); - } else switch (dev->r_ctrl) { - case MSCTRL_COMMAND: - if (val & MSCTRL_FREEZE) { - /* Hold the sampling. */ - ms_update_data(dev); - } else { - /* Reset current state. */ - picintc(1 << dev->irq); - } - - if (val & (MSCTRL_IENB_M | MSCTRL_IENB_A)) - dev->flags |= FLAG_INTR; - else - dev->flags &= ~FLAG_INTR; - - dev->r_cmd = val; - break; - - default: - break; - } - break; - - case MSMOUSE_MAGIC: - break; - - case MSMOUSE_CONFIG: - break; - } -} - - -/* Handle a READ from an InPort register. */ -static uint8_t -ms_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0x00; - - switch (port) { - case MSMOUSE_CTRL: - ret = dev->r_ctrl; - break; - - case MSMOUSE_DATA: - switch (dev->r_ctrl) { - case MSCTRL_RD_BUT: - ret = dev->cur_but; - break; - - case MSCTRL_RD_X: - ret = dev->x; - break; - - case MSCTRL_RD_Y: - ret = dev->y; - break; - - case MSCTRL_COMMAND: - ret = dev->r_cmd; - break; - } - break; - - case MSMOUSE_MAGIC: - if (dev->seq & 0x01) - ret = MAGIC_MSBYTE2; - else - ret = MAGIC_MSBYTE1; - dev->seq ^= 1; - break; - - case MSMOUSE_CONFIG: - /* Not really present in real hardware. */ - break; - } - - return(ret); -} - - -/* Reset the controller state. */ -static void -lt_reset(mouse_t *dev) -{ - dev->r_magic = 0x00; - dev->r_ctrl = (LTCTRL_IENB); - dev->r_conf = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= FLAG_INTR; - - dev->irq_num = 0; -} - - -/* Called at 30hz */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev->flags & FLAG_INPORT) { - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - - if ((dev->flags & FLAG_INTR) && dev->need_upd) { - picint(1 << dev->irq); - mouse_bus_log("IRQ %i raised\n", dev->irq); - } - } else { - picint(1 << dev->irq); - - if (dev->irq_num == 5) { - mouse_bus_log("5th IRQ, enabling mouse...\n"); - lt_reset(dev); - dev->flags |= FLAG_ENABLED; - } - - if (dev->irq_num == 4) { - mouse_bus_log("4th IRQ, going for the 5th...\n"); - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - } else { - mouse_bus_log("IRQ before the 4th, disabling timer...\n"); - dev->timer = 0; - } - } -} - - -/* Handle a WRITE to a Logitech register. */ -static void -lt_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t b; - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - switch(val) { - case LTMAGIC_BYTE1: - case LTMAGIC_BYTE2: - lt_reset(dev); - dev->r_magic = val; - dev->flags |= FLAG_ENABLED; - break; - } - break; - - case LTMOUSE_CTRL: /* [02] control register */ - if (!(dev->flags & FLAG_ENABLED)) { - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - break; - } - - b = (dev->r_ctrl ^ val); - if (b & LTCTRL_FREEZE) { - if (val & LTCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - dev->x = dev->y = 0; - if (dev->but) - dev->but |= 0x80; - } - } - - if (b & LTCTRL_IDIS) { - /* Disable or enable interrupts. */ - if (val & LTCTRL_IDIS) - dev->flags &= ~FLAG_INTR; - else - dev->flags |= FLAG_INTR; - } - - /* Save new register value. */ - dev->r_ctrl = val; - - /* Clear any pending interrupts. */ - picintc(1 << dev->irq); - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - /* - * The original Logitech design was based on using a - * 8255 parallel I/O chip. This chip has to be set up - * for proper operation, and this configuration data - * is what is programmed into this register. - * - * A snippet of code found in the FreeBSD kernel source - * explains the value: - * - * D7 = Mode set flag (1 = active) - * D6,D5 = Mode selection (port A) - * 00 = Mode 0 = Basic I/O - * 01 = Mode 1 = Strobed I/O - * 10 = Mode 2 = Bi-dir bus - * D4 = Port A direction (1 = input) - * D3 = Port C (upper 4 bits) direction. (1 = input) - * D2 = Mode selection (port B & C) - * 0 = Mode 0 = Basic I/O - * 1 = Mode 1 = Strobed I/O - * D1 = Port B direction (1 = input) - * D0 = Port C (lower 4 bits) direction. (1 = input) - * - * So 91 means Basic I/O on all 3 ports, Port A is an input - * port, B is an output port, C is split with upper 4 bits - * being an output port and lower 4 bits an input port, and - * enable the sucker. Courtesy Intel 8255 databook. Lars - */ - dev->r_conf = val; - break; - - default: - break; - } -} - - -/* Handle a READ from a Logitech register. */ -static uint8_t -lt_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0xff; - - /* The GEOS drivers actually check this. */ - if (! (dev->flags & FLAG_ENABLED)) return(ret); - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - ret = 0x07; - if (dev->but & 0x01) /* LEFT */ - ret &= ~0x04; - if (dev->but & 0x02) /* RIGHT */ - ret &= ~0x01; - if (dev->flags & FLAG_3BTN) - if (dev->but & 0x04) /* MIDDLE */ - ret &= ~0x02; - ret <<= 5; - - switch(dev->r_ctrl & LTCTRL_RD_MASK) { - case LTCTRL_RD_X_LO: /* X, low bits */ - ret |= (dev->x & 0x0f); - break; - - case LTCTRL_RD_X_HI: /* X, high bits */ - ret |= (dev->x >> 4) & 0x0f; - break; - - case LTCTRL_RD_Y_LO: /* Y, low bits */ - ret |= (dev->y & 0x0f); - break; - - case LTCTRL_RD_Y_HI: /* Y, high bits */ - ret |= (dev->y >> 4) & 0x0f; - break; - } - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - /* - * Drivers write a magic byte to this register, usually - * this is either 5A (AMI WinBIOS, MS Mouse 2.0) or - * A5 (MS Mouse 9.1, Windows drivers, UNIX/Linux/Minix.) - */ - ret = dev->r_magic; - break; - - case LTMOUSE_CTRL: /* [02] control register */ - ret = 0x0f; - if (!(dev->r_ctrl & LTCTRL_IDIS) && (dev->seq++ == 0)) { - /* !IDIS, return DIP switch setting. */ - switch(dev->irq) { - case 2: - ret &= ~0x08; - break; - - case 3: - ret &= ~0x04; - break; - - case 4: - ret &= ~0x02; - break; - - case 5: - ret &= ~0x01; - break; - } - } - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - ret = dev->r_conf; - break; - - default: - break; - } - - return(ret); -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -bm_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - mouse_bus_log("%s: write(%d,%02x)\n", dev->name, port-MOUSE_PORT, val); - - dev->write(dev, port-MOUSE_PORT, val); -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -bm_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t ret; - - ret = dev->read(dev, port-MOUSE_PORT); - - mouse_bus_log("%s: read(%d): %02x\n", dev->name, port-MOUSE_PORT, ret); - - return(ret); -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Return early if nothing to do. */ - if (!x && !y && !z && (dev->but == b)) - return(1); - - /* If we are not enabled, return. */ - if (! (dev->flags & FLAG_ENABLED)) - mouse_bus_log("bm_poll(): Mouse not enabled\n"); - - if (dev->flags & FLAG_SCALED) { - /* Scale down the motion. */ - if ((x < -1) || (x > 1)) x >>= 1; - if ((y < -1) || (y > 1)) y >>= 1; - } - - if (dev->flags & FLAG_INPORT) { - if (x > 127) x = 127; - if (y > 127) y = 127; - if (x < -128) x = -128; - if (y < -128) y = -128; - - dev->x_delay += x; - dev->y_delay += y; - dev->but = (uint8_t)(0x40 | ((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->flags & FLAG_3BTN) - dev->but |= ((b & 4) >> 1); - dev->need_upd = 1; - } else { - /* If we are frozen, do not update the state. */ - if (! (dev->flags & FLAG_FROZEN)) { - /* Add the delta to our state. */ - x += dev->x; - if (x > 127) - x = 127; - if (x < -128) - x = -128; - dev->x = (int8_t)x; - - y += dev->y; - if (y > 127) - y = 127; - if (y < -1287) - y = -1287; - dev->y = (int8_t)y; - - dev->x_delay += x; - dev->y_delay += y; - - dev->but = b; - } - - /* Either way, generate an interrupt. */ - if ((dev->flags & FLAG_INTR) && !(dev->flags & FLAG_INPORT)) - picint(1 << dev->irq); - } - - return(0); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Release our I/O range. */ - io_removehandler(MOUSE_PORT, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - int i; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - dev->type = info->local; - dev->irq = device_get_config_int("irq"); - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_3BTN; - - mouse_bus_log("%s: I/O=%04x, IRQ=%d, buttons=%d\n", - dev->name, MOUSE_PORT, dev->irq, i); - - switch(dev->type) { - case MOUSE_TYPE_LOGIBUS: - lt_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = lt_read; - dev->write = lt_write; - - dev->timer = 0; - timer_add(bm_timer, &dev->timer, &dev->timer, dev); - break; - - case MOUSE_TYPE_INPORT: - dev->flags |= FLAG_INPORT; - ms_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = ms_read; - dev->write = ms_write; - - dev->timer = (33334LL * TIMER_USEC); - timer_add(bm_timer, &dev->timer, TIMER_ALWAYS_ENABLED, dev); - break; - } - - /* Request an I/O range. */ - io_sethandler(MOUSE_PORT, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); - - /* Return our private data to the I/O layer. */ - return(dev); -} - - -static const device_config_t bm_config[] = { - { - "irq", "IRQ", CONFIG_SELECTION, "", MOUSE_IRQ, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", MOUSE_BUTTONS, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; diff --git a/backup code/mouse_bus_good.c b/backup code/mouse_bus_good.c deleted file mode 100644 index 1f592646e..000000000 --- a/backup code/mouse_bus_good.c +++ /dev/null @@ -1,879 +0,0 @@ -/* - * 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 Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * This code is based on my Minix driver for the Logitech(-mode) - * interface. Although that driver blindly took IRQ5, the board - * seems to be able to tell the driver what IRQ it is set for. - * When testing on MS-DOS (6.22), the 'mouse.exe' driver did not - * want to start, and only after disassembling it and inspecting - * the code it was discovered that driver actually does use the - * IRQ reporting feature. In a really, really weird way, too: it - * sets up the board, and then reads the CTRL register which is - * supposed to return that IRQ value. Depending on whether or - * not the FREEZE bit is set, it has to return either the two's - * complemented (negated) value, or (if clear) just the value. - * The mouse.com driver reads both values 10,000 times, and - * then makes up its mind. Maybe an effort to 'debounce' the - * reading of the DIP switches? Oh-well. - * - * NOTES: Verified with: - * AMI WinBIOS 486 (5A, no IRQ detect, OK, IRQ5 only) - * Microsoft Mouse.com V2.00 (DOS V6.22, 5A, OK) - * Microsoft Mouse.exe V9.1 (DOS V6.22, A5, OK) - * Logitech LMouse.com V6.02 (DOS V6.22) - * Logitech LMouse.com V6.43 (DOS V6.22) - * Microsoft WfW V3.11 on DOS V6.22 - * GEOS V1.0 (OK, IRQ5 only) - * GEOS V2.0 (OK, IRQ5 only) - * Microsoft Windows 95 OSR2 - * Microsoft Windows 98 SE - * Microsoft Windows NT 3.1 - * Microsoft Windows NT 3.51 - * - * The polling frequency for InPort controllers has to - * be changed to programmable. Microsoft uses 30Hz, - * but ATIXL ports are programmable 30-200Hz. - * - * Based on an early driver for MINIX 1.5. - * - * Version: @(#)mouse_bus.c 1.0.38 2018/05/23 - * - * Authors: Fred N. van Kempen, - * - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" - - -#define MOUSE_PORT 0x023c /* default */ -#define MOUSE_IRQ 5 /* default */ -#define MOUSE_BUTTONS 2 /* default */ -#define MOUSE_DEBUG 0 - - -/* Our mouse device. */ -typedef struct mouse { - const char *name; /* name of this device */ - int8_t type; /* type of this device */ - uint16_t base; /* I/O port base to use */ - int8_t irq; /* IRQ channel to use */ - uint16_t flags; /* device flags */ - - uint8_t r_magic, /* MAGIC register */ - r_ctrl, /* CONTROL register (WR) */ - r_conf, /* CONFIG register */ - r_cmd; /* (MS) current command */ - - uint16_t seq; /* general counter */ - - uint8_t but, /* current mouse status */ - but_last; - uint8_t cur_but; - int8_t x, y; - int x_delay, - y_delay; - uint8_t irq_num; - - int64_t timer; /* mouse event timer */ - - uint8_t (*read)(struct mouse *, uint16_t); - void (*write)(struct mouse *, uint16_t, uint8_t); -} mouse_t; -#define FLAG_NEW 0x100 /* device is the newer variant */ -#define FLAG_INPORT 0x80 /* device is MS InPort */ -#define FLAG_3BTN 0x20 /* enable 3-button mode */ -#define FLAG_SCALED 0x10 /* enable delta scaling */ -#define FLAG_INTR 0x04 /* dev can send interrupts */ -#define FLAG_FROZEN 0x02 /* do not update counters */ -#define FLAG_ENABLED 0x01 /* dev is enabled for use */ - - -/* Definitions for Logitech. */ -#define LTMOUSE_DATA 0 /* DATA register */ -#define LTMOUSE_MAGIC 1 /* signature magic register */ -# define LTMAGIC_BYTE1 0xa5 /* most drivers use this */ -# define LTMAGIC_BYTE2 0x5a /* some drivers use this */ -#define LTMOUSE_CTRL 2 /* CTRL register */ -# define LTCTRL_FREEZE 0x80 /* do not sample when set */ -# define LTCTRL_RD_Y_HI 0x60 -# define LTCTRL_RD_Y_LO 0x40 -# define LTCTRL_RD_X_HI 0x20 -# define LTCTRL_RD_X_LO 0x00 -# define LTCTRL_RD_MASK 0x60 -# define LTCTRL_IDIS 0x10 -# define LTCTRL_IENB 0x00 -#define LTMOUSE_CONFIG 3 /* CONFIG register */ - -/* Definitions for Microsoft. */ -#define MSMOUSE_CTRL 0 /* CTRL register */ -# define MSCTRL_RESET 0x80 /* reset controller */ -# define MSCTRL_FREEZE 0x20 /* HOLD- freeze data */ -# define MSCTRL_IENB_A 0x08 /* ATIXL intr enable */ -# define MSCTRL_IENB_M 0x01 /* MS intr enable */ -# define MSCTRL_COMMAND 0x07 -# define MSCTRL_RD_Y 0x02 -# define MSCTRL_RD_X 0x01 -# define MSCTRL_RD_BUT 0x00 -#define MSMOUSE_DATA 1 /* DATA register */ -# define MSDATA_IRQ 0x16 -# define MSDATA_BASE 0x10 /* MS InPort: 30Hz */ -# define MSDATA_HZ30 0x01 /* ATIXL 30Hz */ -# define MSDATA_HZ50 0x02 /* ATIXL 50Hz */ -# define MSDATA_HZ100 0x03 /* ATIXL 100Hz */ -# define MSDATA_HZ200 0x04 /* ATIXL 200Hz */ -#define MSMOUSE_MAGIC 2 /* MAGIC register */ -# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ -# define MAGIC_MSBYTE2 0x12 -#define MSMOUSE_CONFIG 3 /* CONFIG register */ - - -#define ENABLE_MOUSE_BUS_LOG 1 -#ifdef ENABLE_MOUSE_BUS_LOG -int mouse_bus_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -mouse_bus_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (mouse_bus_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Reset the controller state. */ -static void -ms_reset(mouse_t *dev) -{ - dev->r_ctrl = 0x00; - dev->r_cmd = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= (FLAG_INTR | FLAG_ENABLED); - - dev->x_delay = dev->y_delay = 0; - - dev->cur_but = 0x00; -} - - -static void -ms_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - - if (dev->x_delay > 127) { - delta_x = 127; - dev->x_delay -= 127; - } else if (dev->x_delay < -128) { - delta_x = -128; - dev->x_delay += 128; - } else { - delta_x = dev->x_delay; - dev->x_delay = 0; - } - - if (dev->y_delay > 127) { - delta_y = 127; - dev->y_delay -= 127; - } else if (dev->y_delay < -128) { - delta_y = -128; - dev->x_delay += 128; - } else { - delta_y = dev->y_delay; - dev->y_delay = 0; - } - - if (!(dev->flags & FLAG_FROZEN)) { - dev->x = (int8_t) delta_x; - dev->y = (int8_t) delta_y; - dev->cur_but = dev->but; - } -} - - -/* Handle a WRITE to an InPort register. */ -static void -ms_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t valxor; - - switch (port) { - case MSMOUSE_CTRL: - /* Bit 7 is reset. */ - if (val & MSCTRL_RESET) - ms_reset(dev); - - /* Bits 0-2 are the internal register index. */ - switch (val & 0x07) { - case MSCTRL_COMMAND: - case MSCTRL_RD_BUT: - case MSCTRL_RD_X: - case MSCTRL_RD_Y: - dev->r_cmd = val & 0x07; - break; - } - break; - - case MSMOUSE_DATA: - picintc(1 << dev->irq); - - if (val == MSDATA_IRQ) - picint(1 << dev->irq); - else { - switch (dev->r_cmd) { - case MSCTRL_COMMAND: - valxor = (dev->r_ctrl ^ val); - - if (valxor & MSCTRL_FREEZE) { - if (val & MSCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - - dev->x = dev->y = 0; - dev->but = 0; - } - } - - if (val & (MSCTRL_IENB_M | MSCTRL_IENB_A)) - dev->flags |= FLAG_INTR; - else - dev->flags &= ~FLAG_INTR; - - dev->r_ctrl = val; - break; - - default: - break; - } - } - break; - - case MSMOUSE_MAGIC: - break; - - case MSMOUSE_CONFIG: - break; - } -} - - -/* Handle a READ from an InPort register. */ -static uint8_t -ms_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0x00; - - switch (port) { - case MSMOUSE_CTRL: - ret = dev->r_ctrl; - break; - - case MSMOUSE_DATA: - switch (dev->r_cmd) { - case MSCTRL_RD_BUT: - ret = dev->cur_but; - if (dev->flags & FLAG_NEW) - ret |= 0x40; /* On new InPort, always have bit 6 set. */ - break; - - case MSCTRL_RD_X: - ret = dev->x; - break; - - case MSCTRL_RD_Y: - ret = dev->y; - break; - - case MSCTRL_COMMAND: - ret = dev->r_ctrl; - break; - } - break; - - case MSMOUSE_MAGIC: - if (dev->seq & 0x01) - ret = MAGIC_MSBYTE2; - else - ret = MAGIC_MSBYTE1; - dev->seq ^= 1; - break; - - case MSMOUSE_CONFIG: - /* Not really present in real hardware. */ - break; - } - - return(ret); -} - - -/* Reset the controller state. */ -static void -lt_reset(mouse_t *dev) -{ - dev->r_magic = 0x00; - dev->r_ctrl = (LTCTRL_IENB); - dev->r_conf = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= (FLAG_INTR | FLAG_ENABLED); - - dev->irq_num = 0; -} - - -/* Called at 30hz */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev->flags & FLAG_INPORT) { - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - - ms_update_data(dev); - - if (dev->flags & FLAG_INTR) - picint(1 << dev->irq); - } else { - picint(1 << dev->irq); - - if (dev->irq_num == 5) { - mouse_bus_log("5th IRQ, enabling mouse...\n"); - lt_reset(dev); - dev->flags |= FLAG_ENABLED; - } - - if (dev->irq_num == 4) { - mouse_bus_log("4th IRQ, going for the 5th...\n"); - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - } else { - mouse_bus_log("IRQ before the 4th, disabling timer...\n"); - dev->timer = 0; - } - } -} - - -/* Handle a WRITE to a Logitech register. */ -static void -lt_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t b; - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - switch(val) { - case LTMAGIC_BYTE1: - case LTMAGIC_BYTE2: - lt_reset(dev); - dev->r_magic = val; - // dev->flags |= FLAG_ENABLED; - break; - } - break; - - case LTMOUSE_CTRL: /* [02] control register */ -#if 0 - if (!(dev->flags & FLAG_ENABLED)) { - dev->irq_num++; - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - break; - } -#endif - - b = (dev->r_ctrl ^ val); - if (b & LTCTRL_FREEZE) { - if (val & LTCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - dev->x = dev->y = 0; - if (dev->but) - dev->but |= 0x80; - } - } - - if (b & LTCTRL_IDIS) { - /* Disable or enable interrupts. */ - if (val & LTCTRL_IDIS) - dev->flags &= ~FLAG_INTR; - else - dev->flags |= FLAG_INTR; - } - - /* Save new register value. */ - dev->r_ctrl = val | 0x0F; - - /* Clear any pending interrupts. */ - if (val & LTCTRL_FREEZE) { - mouse_bus_log("Freeze: Raise IRQ %i\n", dev->irq); - picint(1 << dev->irq); /* Microsoft MOUSE.SYS v3.0 seems to expect every freeze to send an IRQ? */ - } else { - mouse_bus_log("No freeze: Lower IRQ %i\n", dev->irq); - picintc(1 << dev->irq); - } - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - /* - * The original Logitech design was based on using a - * 8255 parallel I/O chip. This chip has to be set up - * for proper operation, and this configuration data - * is what is programmed into this register. - * - * A snippet of code found in the FreeBSD kernel source - * explains the value: - * - * D7 = Mode set flag (1 = active) - * D6,D5 = Mode selection (port A) - * 00 = Mode 0 = Basic I/O - * 01 = Mode 1 = Strobed I/O - * 10 = Mode 2 = Bi-dir bus - * D4 = Port A direction (1 = input) - * D3 = Port C (upper 4 bits) direction. (1 = input) - * D2 = Mode selection (port B & C) - * 0 = Mode 0 = Basic I/O - * 1 = Mode 1 = Strobed I/O - * D1 = Port B direction (1 = input) - * D0 = Port C (lower 4 bits) direction. (1 = input) - * - * So 91 means Basic I/O on all 3 ports, Port A is an input - * port, B is an output port, C is split with upper 4 bits - * being an output port and lower 4 bits an input port, and - * enable the sucker. Courtesy Intel 8255 databook. Lars - */ - dev->r_conf = val; - break; - - default: - break; - } -} - - -static int -lt_read_int(mouse_t *dev) -{ - if (!(dev->flags & FLAG_NEW)) - return 1; /* On old LogiBus, read the IRQ bits always. */ - - if (dev->flags & FLAG_INTR) - return 1; /* On new LogiBus, read the IRQ bits if interrupts are enabled. */ - - return 0; /* Otherwise, do not. */ -} - - -/* Handle a READ from a Logitech register. */ -static uint8_t -lt_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0xff; - - /* The GEOS drivers actually check this. */ - if (! (dev->flags & FLAG_ENABLED)) return(ret); - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - ret = 0x07; - if (dev->but & 0x01) /* LEFT */ - ret &= ~0x04; - if (dev->but & 0x02) /* RIGHT */ - ret &= ~0x01; - if (dev->flags & FLAG_3BTN) - if (dev->but & 0x04) /* MIDDLE */ - ret &= ~0x02; - ret <<= 5; - - switch(dev->r_ctrl & LTCTRL_RD_MASK) { - case LTCTRL_RD_X_LO: /* X, low bits */ - ret |= (dev->x & 0x0f); - break; - - case LTCTRL_RD_X_HI: /* X, high bits */ - ret |= (dev->x >> 4) & 0x0f; - break; - - case LTCTRL_RD_Y_LO: /* Y, low bits */ - ret |= (dev->y & 0x0f); - break; - - case LTCTRL_RD_Y_HI: /* Y, high bits */ - ret |= (dev->y >> 4) & 0x0f; - break; - } - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - /* - * Drivers write a magic byte to this register, usually - * this is either 5A (AMI WinBIOS, MS Mouse 2.0) or - * A5 (MS Mouse 9.1, Windows drivers, UNIX/Linux/Minix.) - */ - ret = dev->r_magic; - break; - - case LTMOUSE_CTRL: /* [02] control register */ - ret = dev->r_ctrl; - dev->r_ctrl |= 0x0F; - if ((dev->seq > 0x3FF) && lt_read_int(dev)) { - /* !IDIS, return DIP switch setting. */ - switch(dev->irq) { - case 2: - dev->r_ctrl &= ~0x08; - break; - - case 3: - dev->r_ctrl &= ~0x04; - break; - - case 4: - dev->r_ctrl &= ~0x02; - break; - - case 5: - dev->r_ctrl &= ~0x01; - break; - } - } - dev->seq = (dev->seq + 1) & 0x7ff; - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - ret = dev->r_conf; - break; - - default: - break; - } - - return(ret); -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -bm_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - mouse_bus_log("%s: write(%d,%02x)\n", dev->name, port & 0x03, val); - - dev->write(dev, port & 0x03, val); -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -bm_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t ret; - - ret = dev->read(dev, port & 0x03); - - mouse_bus_log("%s: read(%d): %02x\n", dev->name, port & 0x03, ret); - - return(ret); -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - uint8_t b_last; - mouse_t *dev = (mouse_t *)priv; - - b_last = dev->but; - - /* Return early if nothing to do. */ - if (!x && !y && !z && (dev->but == b)) - return(1); - - /* If we are not enabled, return. */ - if (! (dev->flags & FLAG_ENABLED)) - mouse_bus_log("bm_poll(): Mouse not enabled\n"); - - if (dev->flags & FLAG_SCALED) { - /* Scale down the motion. */ - if ((x < -1) || (x > 1)) x >>= 1; - if ((y < -1) || (y > 1)) y >>= 1; - } - - if (dev->flags & FLAG_INPORT) { - if (x || y || z) - dev->but = 0x40; /* Mouse has moved. */ - else - dev->but = 0x00; - - if (x > 127) x = 127; - if (y > 127) y = 127; - if (x < -128) x = -128; - if (y < -128) y = -128; - - dev->x_delay += x; - dev->y_delay += y; - dev->but |= (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->flags & FLAG_3BTN) - dev->but |= ((b & 4) >> 1); - - if ((b_last ^ dev->but) & 0x04) - dev->but |= 0x20; /* Left button state has changed. */ - if (((b_last ^ dev->but) & 0x02) && (dev->flags & FLAG_3BTN)) - dev->but |= 0x10; /* Middle button state has changed. */ - if ((b_last ^ dev->but) & 0x01) - dev->but |= 0x08; /* Right button state has changed. */ - - dev->but |= 0x80; /* Packet complete. */ - } else { - /* If we are frozen, do not update the state. */ - if (! (dev->flags & FLAG_FROZEN)) { - /* Add the delta to our state. */ - x += dev->x; - if (x > 127) - x = 127; - if (x < -128) - x = -128; - dev->x = (int8_t)x; - - y += dev->y; - if (y > 127) - y = 127; - if (y < -1287) - y = -1287; - dev->y = (int8_t)y; - - dev->x_delay += x; - dev->y_delay += y; - - dev->but = b; - } - - /* Either way, generate an interrupt. */ - if ((dev->flags & FLAG_INTR) && !(dev->flags & FLAG_INPORT)) - picint(1 << dev->irq); - } - - return(0); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Release our I/O range. */ - io_removehandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - int i, j; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - dev->type = info->local; - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_3BTN; - j = device_get_config_int("model"); - if (j) - dev->flags |= FLAG_NEW; - - switch(dev->type) { - case MOUSE_TYPE_LOGIBUS: - lt_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = lt_read; - dev->write = lt_write; - - // dev->timer = 0; - // timer_add(bm_timer, &dev->timer, &dev->timer, dev); - break; - - case MOUSE_TYPE_INPORT: - dev->flags |= FLAG_INPORT; - ms_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = ms_read; - dev->write = ms_write; - - dev->timer = (33334LL * TIMER_USEC); - timer_add(bm_timer, &dev->timer, TIMER_ALWAYS_ENABLED, dev); - break; - } - - /* Request an I/O range. */ - io_sethandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - mouse_bus_log("%s: I/O=%04x, IRQ=%d, buttons=%d, model=%s\n", - dev->name, dev->base, dev->irq, i, j ? "new" : "old"); - - /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); - - /* Return our private data to the I/O layer. */ - return(dev); -} - - -static const device_config_t bm_config[] = { - { - "base", "Address", CONFIG_HEX16, "", MOUSE_PORT, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", MOUSE_IRQ, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", MOUSE_BUTTONS, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "model", "Model", CONFIG_SELECTION, "", 0, { - { - "Old", 0 - }, - { - "New", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; diff --git a/backup code/mouse_bus_x.c b/backup code/mouse_bus_x.c deleted file mode 100644 index 62fae5e53..000000000 --- a/backup code/mouse_bus_x.c +++ /dev/null @@ -1,795 +0,0 @@ -/* - * 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 Bus Mouse devices. - * - * These devices were made by both Microsoft and Logitech. At - * first, Microsoft used the same protocol as Logitech, but did - * switch to their new protocol for their InPort interface. So, - * although alike enough to be handled in the same driver, they - * are not the same. - * - * This code is based on my Minix driver for the Logitech(-mode) - * interface. Although that driver blindly took IRQ5, the board - * seems to be able to tell the driver what IRQ it is set for. - * When testing on MS-DOS (6.22), the 'mouse.exe' driver did not - * want to start, and only after disassembling it and inspecting - * the code it was discovered that driver actually does use the - * IRQ reporting feature. In a really, really weird way, too: it - * sets up the board, and then reads the CTRL register which is - * supposed to return that IRQ value. Depending on whether or - * not the FREEZE bit is set, it has to return either the two's - * complemented (negated) value, or (if clear) just the value. - * The mouse.com driver reads both values 10,000 times, and - * then makes up its mind. Maybe an effort to 'debounce' the - * reading of the DIP switches? Oh-well. - * - * NOTES: Verified with: - * AMI WinBIOS 486 (5A, no IRQ detect, OK, IRQ5 only) - * Microsoft Mouse.com V2.00 (DOS V6.22, 5A, OK) - * Microsoft Mouse.exe V9.1 (DOS V6.22, A5, OK) - * Logitech LMouse.com V6.02 (DOS V6.22) - * Logitech LMouse.com V6.43 (DOS V6.22) - * Microsoft WfW V3.11 on DOS V6.22 - * GEOS V1.0 (OK, IRQ5 only) - * GEOS V2.0 (OK, IRQ5 only) - * Microsoft Windows 95 OSR2 - * Microsoft Windows 98 SE - * Microsoft Windows NT 3.1 - * Microsoft Windows NT 3.51 - * - * The polling frequency for InPort controllers has to - * be changed to programmable. Microsoft uses 30Hz, - * but ATIXL ports are programmable 30-200Hz. - * - * Based on an early driver for MINIX 1.5. - * - * Version: @(#)mouse_bus.c 1.0.39 2018/05/24 - * - * Authors: Fred N. van Kempen, - * - * Copyright 1989-2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "device.h" -#include "mouse.h" - - -#define MOUSE_PORT 0x023c /* default */ -#define MOUSE_IRQ 5 /* default */ -#define MOUSE_BUTTONS 2 /* default */ -#define MOUSE_DEBUG 0 - - -/* Our mouse device. */ -typedef struct mouse { - const char *name; /* name of this device */ - int8_t type; /* type of this device */ - uint16_t base; /* I/O port base to use */ - int8_t irq; /* IRQ channel to use */ - uint16_t flags; /* device flags */ - - uint8_t r_magic, /* MAGIC register */ - r_ctrl, /* CONTROL register (WR) */ - r_conf, /* CONFIG register */ - r_cmd; /* (MS) current command */ - - uint16_t seq; /* general counter */ - - uint8_t but, /* current mouse status */ - but_last; - uint8_t cur_but; - int8_t x, y; - int x_delay, - y_delay; - uint8_t irq_num; - - int64_t timer; /* mouse event timer */ - - uint8_t (*read)(struct mouse *, uint16_t); - void (*write)(struct mouse *, uint16_t, uint8_t); -} mouse_t; -#define FLAG_NEW 0x100 /* device is the newer variant */ -#define FLAG_INPORT 0x80 /* device is MS InPort */ -#define FLAG_3BTN 0x20 /* enable 3-button mode */ -#define FLAG_SCALED 0x10 /* enable delta scaling */ -#define FLAG_INTR 0x04 /* dev can send interrupts */ -#define FLAG_FROZEN 0x02 /* do not update counters */ -#define FLAG_ENABLED 0x01 /* dev is enabled for use */ - - -/* Definitions for Logitech. */ -#define LTMOUSE_DATA 0 /* DATA register */ -#define LTMOUSE_MAGIC 1 /* signature magic register */ -# define LTMAGIC_BYTE1 0xa5 /* most drivers use this */ -# define LTMAGIC_BYTE2 0x5a /* some drivers use this */ -#define LTMOUSE_CTRL 2 /* CTRL register */ -# define LTCTRL_FREEZE 0x80 /* do not sample when set */ -# define LTCTRL_RD_Y_HI 0x60 -# define LTCTRL_RD_Y_LO 0x40 -# define LTCTRL_RD_X_HI 0x20 -# define LTCTRL_RD_X_LO 0x00 -# define LTCTRL_RD_MASK 0x60 -# define LTCTRL_IDIS 0x10 -# define LTCTRL_IENB 0x00 -#define LTMOUSE_CONFIG 3 /* CONFIG register */ - -/* Definitions for Microsoft. */ -#define MSMOUSE_CTRL 0 /* CTRL register */ -# define MSCTRL_RESET 0x80 /* reset controller */ -# define MSCTRL_FREEZE 0x20 /* HOLD- freeze data */ -# define MSCTRL_IENB_A 0x08 /* ATIXL intr enable */ -# define MSCTRL_IENB_M 0x01 /* MS intr enable */ -# define MSCTRL_COMMAND 0x07 -# define MSCTRL_RD_Y 0x02 -# define MSCTRL_RD_X 0x01 -# define MSCTRL_RD_BUT 0x00 -#define MSMOUSE_DATA 1 /* DATA register */ -# define MSDATA_IRQ 0x16 -# define MSDATA_BASE 0x10 /* MS InPort: 30Hz */ -# define MSDATA_HZ30 0x01 /* ATIXL 30Hz */ -# define MSDATA_HZ50 0x02 /* ATIXL 50Hz */ -# define MSDATA_HZ100 0x03 /* ATIXL 100Hz */ -# define MSDATA_HZ200 0x04 /* ATIXL 200Hz */ -#define MSMOUSE_MAGIC 2 /* MAGIC register */ -# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ -# define MAGIC_MSBYTE2 0x12 -#define MSMOUSE_CONFIG 3 /* CONFIG register */ - - -#define ENABLE_MOUSE_BUS_LOG 1 -#ifdef ENABLE_MOUSE_BUS_LOG -int mouse_bus_do_log = ENABLE_MOUSE_BUS_LOG; -#endif - - -static void -mouse_bus_log(const char *format, ...) -{ -#ifdef ENABLE_MOUSE_BUS_LOG - va_list ap; - - if (mouse_bus_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* Reset the controller state. */ -static void -ms_reset(mouse_t *dev) -{ - dev->r_ctrl = 0x00; - dev->r_cmd = 0x00; - - dev->seq = 0; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->flags &= 0xf0; - dev->flags |= (FLAG_INTR | FLAG_ENABLED); - - dev->x_delay = dev->y_delay = 0; - - dev->cur_but = 0x00; -} - - -static void -bm_update_data(mouse_t *dev) -{ - int delta_x, delta_y; - - if (dev->x_delay > 127) { - delta_x = 127; - dev->x_delay -= 127; - } else if (dev->x_delay < -128) { - delta_x = -128; - dev->x_delay += 128; - } else { - delta_x = dev->x_delay; - dev->x_delay = 0; - } - - if (dev->y_delay > 127) { - delta_y = 127; - dev->y_delay -= 127; - } else if (dev->y_delay < -128) { - delta_y = -128; - dev->x_delay += 128; - } else { - delta_y = dev->y_delay; - dev->y_delay = 0; - } - - if (!(dev->flags & FLAG_FROZEN)) { - dev->x = (int8_t) delta_x; - dev->y = (int8_t) delta_y; - dev->cur_but = dev->but; - } -} - - -/* Handle a WRITE to an InPort register. */ -static void -ms_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t valxor; - - switch (port) { - case MSMOUSE_CTRL: - /* Bit 7 is reset. */ - if (val & MSCTRL_RESET) - ms_reset(dev); - - /* Bits 0-2 are the internal register index. */ - switch (val & 0x07) { - case MSCTRL_COMMAND: - case MSCTRL_RD_BUT: - case MSCTRL_RD_X: - case MSCTRL_RD_Y: - dev->r_cmd = val & 0x07; - break; - } - break; - - case MSMOUSE_DATA: - picintc(1 << dev->irq); - - if (val == MSDATA_IRQ) - picint(1 << dev->irq); - else { - switch (dev->r_cmd) { - case MSCTRL_COMMAND: - valxor = (dev->r_ctrl ^ val); - - if (valxor & MSCTRL_FREEZE) { - if (val & MSCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - - dev->x = dev->y = 0; - dev->but = 0; - } - } - - if (val & (MSCTRL_IENB_M | MSCTRL_IENB_A)) - dev->flags |= FLAG_INTR; - else - dev->flags &= ~FLAG_INTR; - - dev->r_ctrl = val; - break; - - default: - break; - } - } - break; - - case MSMOUSE_MAGIC: - break; - - case MSMOUSE_CONFIG: - break; - } -} - - -/* Handle a READ from an InPort register. */ -static uint8_t -ms_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0x00; - - switch (port) { - case MSMOUSE_CTRL: - ret = dev->r_ctrl; - break; - - case MSMOUSE_DATA: - switch (dev->r_cmd) { - case MSCTRL_RD_BUT: - ret = dev->cur_but; - if (dev->flags & FLAG_NEW) - ret |= 0x40; /* On new InPort, always have bit 6 set. */ - break; - - case MSCTRL_RD_X: - ret = dev->x; - break; - - case MSCTRL_RD_Y: - ret = dev->y; - break; - - case MSCTRL_COMMAND: - ret = dev->r_ctrl; - break; - } - break; - - case MSMOUSE_MAGIC: - if (dev->seq & 0x01) - ret = MAGIC_MSBYTE2; - else - ret = MAGIC_MSBYTE1; - dev->seq ^= 1; - break; - - case MSMOUSE_CONFIG: - /* Not really present in real hardware. */ - break; - } - - return(ret); -} - - -/* Reset the controller state. */ -static void -lt_reset(mouse_t *dev) -{ - dev->r_ctrl = (LTCTRL_IENB) | 0x0f; - dev->r_conf = 0x0e; - dev->r_magic = 0x00; - - dev->seq = 0; - dev->flags &= 0xf0; - dev->flags |= FLAG_INTR; - - dev->x = dev->y = 0; - dev->but = 0x00; - - dev->irq_num = 0; -} - - -/* Called at 30hz */ -static void -bm_timer(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - if (dev->flags & FLAG_INPORT) - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - else - dev->timer = ((1000000LL * TIMER_USEC) / 200LL); - - bm_update_data(dev); - - if (dev->flags & FLAG_INTR) { - picint(1 << dev->irq); - mouse_bus_log("Mouse IRQ %i\n", dev->irq); - } -} - - -/* Handle a WRITE to a Logitech register. */ -static void -lt_write(mouse_t *dev, uint16_t port, uint8_t val) -{ - uint8_t b; - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - dev->r_magic = val; - break; - - case LTMOUSE_CTRL: /* [02] control register */ - b = (dev->r_ctrl ^ val); - if (b & LTCTRL_FREEZE) { - if (val & LTCTRL_FREEZE) { - /* Hold the sampling while we do something. */ - dev->flags |= FLAG_FROZEN; - } else { - /* Reset current state. */ - dev->flags &= ~FLAG_FROZEN; - dev->x = dev->y = 0; - if (dev->but) - dev->but |= 0x80; - } - } - - if (b & LTCTRL_IDIS) { - /* Disable or enable interrupts. */ - if (val & LTCTRL_IDIS) - dev->flags &= ~FLAG_INTR; - else - dev->flags |= FLAG_INTR; - } - - /* Save new register value. */ - dev->r_ctrl = val | 0x0F; - - /* Clear any pending interrupts. */ - picintc(1 << dev->irq); - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - /* - * The original Logitech design was based on using a - * 8255 parallel I/O chip. This chip has to be set up - * for proper operation, and this configuration data - * is what is programmed into this register. - * - * A snippet of code found in the FreeBSD kernel source - * explains the value: - * - * D7 = Mode set flag (1 = active) - * D6,D5 = Mode selection (port A) - * 00 = Mode 0 = Basic I/O - * 01 = Mode 1 = Strobed I/O - * 10 = Mode 2 = Bi-dir bus - * D4 = Port A direction (1 = input) - * D3 = Port C (upper 4 bits) direction. (1 = input) - * D2 = Mode selection (port B & C) - * 0 = Mode 0 = Basic I/O - * 1 = Mode 1 = Strobed I/O - * D1 = Port B direction (1 = input) - * D0 = Port C (lower 4 bits) direction. (1 = input) - * - * So 91 means Basic I/O on all 3 ports, Port A is an input - * port, B is an output port, C is split with upper 4 bits - * being an output port and lower 4 bits an input port, and - * enable the sucker. Courtesy Intel 8255 databook. Lars - */ - dev->r_conf = val; - break; - - default: - break; - } -} - - -static int -lt_read_int(mouse_t *dev) -{ - if (!(dev->flags & FLAG_NEW)) - return 1; /* On old LogiBus, read the IRQ bits always. */ - - if (dev->flags & FLAG_INTR) - return 1; /* On new LogiBus, read the IRQ bits if interrupts are enabled. */ - - return 0; /* Otherwise, do not. */ -} - - -/* Handle a READ from a Logitech register. */ -static uint8_t -lt_read(mouse_t *dev, uint16_t port) -{ - uint8_t ret = 0xff; - - /* The GEOS drivers actually check this. */ - if (! (dev->flags & FLAG_ENABLED)) return(ret); - - switch (port) { - case LTMOUSE_DATA: /* [00] data register */ - ret = 0x07; - if (dev->cur_but & 0x01) /* LEFT */ - ret &= ~0x04; - if (dev->cur_but & 0x02) /* RIGHT */ - ret &= ~0x01; - if (dev->flags & FLAG_3BTN) - if (dev->cur_but & 0x04) /* MIDDLE */ - ret &= ~0x02; - ret <<= 5; - - switch(dev->r_ctrl & LTCTRL_RD_MASK) { - case LTCTRL_RD_X_LO: /* X, low bits */ - ret |= (dev->x & 0x0f); - break; - - case LTCTRL_RD_X_HI: /* X, high bits */ - ret |= (dev->x >> 4) & 0x0f; - break; - - case LTCTRL_RD_Y_LO: /* Y, low bits */ - ret |= (dev->y & 0x0f); - break; - - case LTCTRL_RD_Y_HI: /* Y, high bits */ - ret |= (dev->y >> 4) & 0x0f; - break; - } - break; - - case LTMOUSE_MAGIC: /* [01] magic data register */ - /* - * Drivers write a magic byte to this register, usually - * this is either 5A (AMI WinBIOS, MS Mouse 2.0) or - * A5 (MS Mouse 9.1, Windows drivers, UNIX/Linux/Minix.) - */ - ret = dev->r_magic; - break; - - case LTMOUSE_CTRL: /* [02] control register */ - ret = dev->r_ctrl; - dev->r_ctrl |= 0x0F; - if ((dev->seq > 0x3FF) && lt_read_int(dev)) - dev->r_ctrl &= ~((1 << 5) >> dev->irq); - dev->seq = (dev->seq + 1) & 0x7ff; - break; - - case LTMOUSE_CONFIG: /* [03] config register */ - ret = dev->r_conf; - break; - - default: - break; - } - - return(ret); -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -bm_write(uint16_t port, uint8_t val, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - mouse_bus_log("%s: write(%d,%02x)\n", dev->name, port & 0x03, val); - - dev->write(dev, port & 0x03, val); -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -bm_read(uint16_t port, void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - uint8_t ret; - - ret = dev->read(dev, port & 0x03); - - mouse_bus_log("%s: read(%d): %02x\n", dev->name, port & 0x03, ret); - - return(ret); -} - - -/* The emulator calls us with an update on the host mouse device. */ -static int -bm_poll(int x, int y, int z, int b, void *priv) -{ - uint8_t b_last; - mouse_t *dev = (mouse_t *)priv; - - b_last = dev->but; - - if (dev->flags & FLAG_INPORT) { - if (x || y || z) - dev->but = 0x40; /* Mouse has moved. */ - else - dev->but = 0x00; - } else - dev->but = 0x00; - - if (dev->flags & FLAG_SCALED) { - /* Scale down the motion. */ - if ((x < -1) || (x > 1)) x >>= 1; - if ((y < -1) || (y > 1)) y >>= 1; - } - - if (x > 127) x = 127; - if (y > 127) y = 127; - if (x < -128) x = -128; - if (y < -128) y = -128; - - dev->x_delay += x; - dev->y_delay += y; - - /* Change button state MRL to LMR */ - dev->but |= (uint8_t) (((b & 1) << 2) | ((b & 2) >> 1)); - if (dev->flags & FLAG_3BTN) - dev->but |= ((b & 4) >> 1); - - if (dev->flags & FLAG_INPORT) { - if ((b_last ^ dev->but) & 0x04) - dev->but |= 0x20; /* Left button state has changed. */ - if (((b_last ^ dev->but) & 0x02) && (dev->flags & FLAG_3BTN)) - dev->but |= 0x10; /* Middle button state has changed. */ - if ((b_last ^ dev->but) & 0x01) - dev->but |= 0x08; /* Right button state has changed. */ - - dev->but |= 0x80; /* Packet complete. */ - } - - return(0); -} - - -/* Release all resources held by the device. */ -static void -bm_close(void *priv) -{ - mouse_t *dev = (mouse_t *)priv; - - /* Release our I/O range. */ - io_removehandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - free(dev); -} - - -/* Initialize the device for use by the user. */ -static void * -bm_init(const device_t *info) -{ - mouse_t *dev; - int i, j; - - dev = (mouse_t *)malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); - dev->name = info->name; - dev->type = info->local; - dev->base = device_get_config_hex16("base"); - dev->irq = device_get_config_int("irq"); - i = device_get_config_int("buttons"); - if (i > 2) - dev->flags |= FLAG_3BTN; - j = device_get_config_int("model"); - if (j) - dev->flags |= FLAG_NEW; - - switch(dev->type) { - case MOUSE_TYPE_LOGIBUS: - lt_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = lt_read; - dev->write = lt_write; - - dev->timer = ((1000000LL * TIMER_USEC) / 200LL); - break; - - case MOUSE_TYPE_INPORT: - dev->flags |= FLAG_INPORT; - ms_reset(dev); - - /* Initialize I/O handlers. */ - dev->read = ms_read; - dev->write = ms_write; - - dev->timer = ((1000000LL * TIMER_USEC) / 30LL); - break; - } - - timer_add(bm_timer, &dev->timer, TIMER_ALWAYS_ENABLED, dev); - - /* Request an I/O range. */ - io_sethandler(dev->base, 4, - bm_read, NULL, NULL, bm_write, NULL, NULL, dev); - - mouse_bus_log("%s: I/O=%04x, IRQ=%d, buttons=%d, model=%s\n", - dev->name, dev->base, dev->irq, i, j ? "new" : "old"); - - /* Tell them how many buttons we have. */ - mouse_set_buttons((dev->flags & FLAG_3BTN) ? 3 : 2); - - /* Return our private data to the I/O layer. */ - return(dev); -} - - -static const device_config_t bm_config[] = { - { - "base", "Address", CONFIG_HEX16, "", MOUSE_PORT, - { - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x238", 0x238 - }, - { - "0x23C", 0x23c - }, - { - "" - } - } - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", MOUSE_IRQ, { - { - "IRQ 2", 2 - }, - { - "IRQ 3", 3 - }, - { - "IRQ 4", 4 - }, - { - "IRQ 5", 5 - }, - { - "" - } - } - }, - { - "buttons", "Buttons", CONFIG_SELECTION, "", MOUSE_BUTTONS, { - { - "Two", 2 - }, - { - "Three", 3 - }, - { - "" - } - } - }, - { - "model", "Model", CONFIG_SELECTION, "", 0, { - { - "Old", 0 - }, - { - "New", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mouse_logibus_device = { - "Logitech Bus Mouse", - DEVICE_ISA, - MOUSE_TYPE_LOGIBUS, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; - -const device_t mouse_msinport_device = { - "Microsoft Bus Mouse (InPort)", - DEVICE_ISA, - MOUSE_TYPE_INPORT, - bm_init, bm_close, NULL, - bm_poll, NULL, NULL, - bm_config -}; diff --git a/backup code/network/net_pcap - Cópia.c b/backup code/network/net_pcap - Cópia.c deleted file mode 100644 index a619868b6..000000000 --- a/backup code/network/net_pcap - Cópia.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * 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 - * spanning the era between 1981 and 1995. - * - * This file is part of the VARCem Project. - * - * Handle WinPcap library processing. - * - * Version: @(#)net_pcap.c 1.0.3 2018/03/15 - * - * Author: Fred N. van Kempen, - * - * Copyright 2017,2018 Fred N. van Kempen. - * - * 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. - * - * 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. - * - * 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 - * 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 - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../config.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_dynld.h" -#include "network.h" - - -static volatile void *pcap_handle; /* handle to WinPcap DLL */ -static volatile pcap_t *pcap; /* handle to WinPcap library */ -static volatile thread_t *poll_tid; -static const netcard_t *poll_card; /* netcard linked to us */ -static event_t *poll_state; - - -/* Pointers to the real functions. */ -static const char *(*f_pcap_lib_version)(void); -static int (*f_pcap_findalldevs)(pcap_if_t **,char *); -static void (*f_pcap_freealldevs)(pcap_if_t *); -static pcap_t *(*f_pcap_open_live)(const char *,int,int,int,char *); -static int (*f_pcap_compile)(pcap_t *,struct bpf_program *, - const char *,int,bpf_u_int32); -static int (*f_pcap_setfilter)(pcap_t *,struct bpf_program *); -static const u_char *(*f_pcap_next)(pcap_t *,struct pcap_pkthdr *); -static int (*f_pcap_sendpacket)(pcap_t *,const u_char *,int); -static void (*f_pcap_close)(pcap_t *); -static dllimp_t pcap_imports[] = { - { "pcap_lib_version", &f_pcap_lib_version }, - { "pcap_findalldevs", &f_pcap_findalldevs }, - { "pcap_freealldevs", &f_pcap_freealldevs }, - { "pcap_open_live", &f_pcap_open_live }, - { "pcap_compile", &f_pcap_compile }, - { "pcap_setfilter", &f_pcap_setfilter }, - { "pcap_next", &f_pcap_next }, - { "pcap_sendpacket", &f_pcap_sendpacket }, - { "pcap_close", &f_pcap_close }, - { NULL, NULL }, -}; - - -/* Handle the receiving of frames from the channel. */ -static void -poll_thread(void *arg) -{ - uint8_t *mac = (uint8_t *)arg; - uint8_t *data = NULL; - struct pcap_pkthdr h; - uint32_t mac_cmp32[2]; - uint16_t mac_cmp16[2]; - event_t *evt; - - pclog("PCAP: polling started.\n"); - thread_set_event(poll_state); - - /* Create a waitable event. */ - evt = thread_create_event(); - - /* As long as the channel is open.. */ - while (pcap != NULL) { - /* Request ownership of the device. */ - network_wait(1); - - /* Wait for a poll request. */ - network_poll(); - - if (pcap == NULL) break; - - /* Wait for the next packet to arrive. */ - data = (uint8_t *)f_pcap_next((pcap_t *)pcap, &h); - if (data != NULL) { - /* Received MAC. */ - mac_cmp32[0] = *(uint32_t *)(data+6); - mac_cmp16[0] = *(uint16_t *)(data+10); - - /* Local MAC. */ - mac_cmp32[1] = *(uint32_t *)mac; - mac_cmp16[1] = *(uint16_t *)(mac+4); - if ((mac_cmp32[0] != mac_cmp32[1]) || - (mac_cmp16[0] != mac_cmp16[1])) { - - poll_card->rx(poll_card->priv, data, h.caplen); - } else { - /* Mark as invalid packet. */ - data = NULL; - } - } - - /* If we did not get anything, wait a while. */ - if (data == NULL) - thread_wait_event(evt, 10); - - /* Release ownership of the device. */ - network_wait(0); - } - - /* No longer needed. */ - if (evt != NULL) - thread_destroy_event(evt); - - pclog("PCAP: polling stopped.\n"); - thread_set_event(poll_state); -} - - -/* - * Prepare the (Win)Pcap module for use. - * - * This is called only once, during application init, - * to check for availability of PCAP, and to retrieve - * a list of (usable) intefaces for it. - */ -int -net_pcap_prepare(netdev_t *list) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - pcap_if_t *devlist, *dev; - int i = 0; - - /* Local variables. */ - pcap = NULL; - - /* Try loading the DLL. */ -#ifdef _WIN32 - pcap_handle = dynld_module("wpcap.dll", pcap_imports); -#else - pcap_handle = dynld_module("libpcap.so", pcap_imports); -#endif - if (pcap_handle == NULL) return(-1); - - /* Retrieve the device list from the local machine */ - if (f_pcap_findalldevs(&devlist, errbuf) == -1) { - pclog("PCAP: error in pcap_findalldevs: %s\n", errbuf); - return(-1); - } - - for (dev=devlist; dev!=NULL; dev=dev->next) { - strcpy(list->device, dev->name); - if (dev->description) - strcpy(list->description, dev->description); - else - memset(list->description, '\0', sizeof(list->description)); - list++; i++; - } - - /* Release the memory. */ - f_pcap_freealldevs(devlist); - - return(i); -} - - -/* - * Initialize (Win)Pcap for use. - * - * This is called on every 'cycle' of the emulator, - * if and as long the NetworkType is set to PCAP, - * and also as long as we have a NetCard defined. - */ -int -net_pcap_init(void) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - char *str; - - /* Did we already load the library? */ - if (pcap_handle == NULL) return(-1); -#if 0 - // no, we don't.. - /* Load the DLL if needed. We already know it exists. */ -#ifdef _WIN32 - pcap_handle = dynld_module("wpcap.dll", pcap_imports); -#else - pcap_handle = dynld_module("libpcap.so", pcap_imports); -#endif - if (pcap_handle == NULL) return(-1); -#endif - - /* Get the PCAP library name and version. */ - strcpy(errbuf, f_pcap_lib_version()); - str = strchr(errbuf, '('); - if (str != NULL) *(str-1) = '\0'; - pclog("PCAP: initializing, %s\n", errbuf); - - /* Get the value of our capture interface. */ - if ((network_host[0] == '\0') || !strcmp(network_host, "none")) { - pclog("PCAP: no interface configured!\n"); - return(-1); - } - - poll_tid = NULL; - poll_state = NULL; - poll_card = NULL; - - return(0); -} - - -/* Close up shop. */ -void -net_pcap_close(void) -{ - pcap_t *pc; - - if (pcap == NULL) return; - - pclog("PCAP: closing.\n"); - - /* Tell the polling thread to shut down. */ - pc = (pcap_t *)pcap; pcap = NULL; - - /* Tell the thread to terminate. */ - if (poll_tid != NULL) { - network_busy(0); - - /* Wait for the thread to finish. */ - pclog("PCAP: waiting for thread to end...\n"); - thread_wait_event(poll_state, -1); - pclog("PCAP: thread ended\n"); - thread_destroy_event(poll_state); - - poll_tid = NULL; - poll_state = NULL; - poll_card = NULL; - } - - /* OK, now shut down Pcap itself. */ - f_pcap_close(pc); - pcap = NULL; - -#if 0 - // no, we don't.. - /* Unload the DLL if possible. */ - if (pcap_handle != NULL) { - dynld_close((void *)pcap_handle); - pcap_handle = NULL; - } -#endif -} - - -/* - * Reset (Win)Pcap and activate it. - * - * This is called on every 'cycle' of the emulator, - * if and as long the NetworkType is set to PCAP, - * and also as long as we have a NetCard defined. - * - * We already know we have PCAP available, as this - * is called when the network activates itself and - * tries to attach to the network module. - */ -int -net_pcap_reset(const netcard_t *card, uint8_t *mac) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - char filter_exp[255]; - struct bpf_program fp; - - /* Open a PCAP live channel. */ - if ((pcap = f_pcap_open_live(network_host, /* interface name */ - 1518, /* max packet size */ - 1, /* promiscuous mode? */ - 10, /* timeout in msec */ - errbuf)) == NULL) { /* error buffer */ - pclog(" Unable to open device: %s!\n", network_host); - return(-1); - } - pclog("PCAP: interface: %s\n", network_host); - - /* Create a MAC address based packet filter. */ - pclog("PCAP: installing filter for MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - sprintf(filter_exp, - "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - if (f_pcap_compile((pcap_t *)pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { - if (f_pcap_setfilter((pcap_t *)pcap, &fp) != 0) { - pclog("PCAP: error installing filter (%s) !\n", filter_exp); - f_pcap_close((pcap_t *)pcap); - return(-1); - } - } else { - pclog("PCAP: could not compile filter (%s) !\n", filter_exp); - f_pcap_close((pcap_t *)pcap); - return(-1); - } - - /* Save the callback info. */ - poll_card = card; - - pclog("PCAP: starting thread..\n"); - poll_state = thread_create_event(); - poll_tid = thread_create(poll_thread, mac); - thread_wait_event(poll_state, -1); - - return(0); -} - - -/* Send a packet to the Pcap interface. */ -void -net_pcap_in(uint8_t *bufp, int len) -{ - if (pcap == NULL) return; - - network_busy(1); - - f_pcap_sendpacket((pcap_t *)pcap, bufp, len); - - network_busy(0); -} diff --git a/backup code/pc - Cópia.c b/backup code/pc - Cópia.c deleted file mode 100644 index 7c627b18c..000000000 --- a/backup code/pc - Cópia.c +++ /dev/null @@ -1,1130 +0,0 @@ -/* - * 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. - * - * Main emulator module where most things are controlled. - * - * Version: @(#)pc.c 1.0.72 2018/05/25 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "config.h" -#include "cpu/cpu.h" -#ifdef USE_DYNAREC -# include "cpu/codegen.h" -#endif -#include "cpu/x86_ops.h" -#include "io.h" -#include "mem.h" -#include "rom.h" -#include "dma.h" -#include "pci.h" -#include "pic.h" -#include "pit.h" -#include "random.h" -#include "timer.h" -#include "device.h" -#include "nvr.h" -#include "machine/machine.h" -#include "bugger.h" -#include "lpt.h" -#include "serial.h" -#include "keyboard.h" -#include "mouse.h" -#include "game/gameport.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" -#include "disk/hdd.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "disk/zip.h" -#include "scsi/scsi.h" -#include "cdrom/cdrom.h" -#include "cdrom/cdrom_image.h" -#include "cdrom/cdrom_null.h" -#include "network/network.h" -#include "sound/sound.h" -#include "sound/midi.h" -#include "sound/snd_speaker.h" -#include "video/video.h" -#include "ui.h" -#include "plat.h" -#include "plat_midi.h" - - -/* Commandline options. */ -int dump_on_exit = 0; /* (O) dump regs on exit */ -int do_dump_config = 0; /* (O) dump config on load */ -int start_in_fullscreen = 0; /* (O) start in fullscreen */ -#ifdef _WIN32 -int force_debug = 0; /* (O) force debug output */ -#endif -#ifdef USE_WX -int video_fps = RENDER_FPS; /* (O) render speed in fps */ -#endif -int settings_only = 0; /* (O) show only the settings dialog */ -#ifdef _WIN32 -uint64_t unique_id = 0; -uint64_t source_hwnd = 0; -#endif -wchar_t log_path[1024] = { L'\0'}; /* (O) full path of logfile */ - -/* Configuration values. */ -int window_w, window_h, /* (C) window size and */ - window_x, window_y, /* position info */ - window_remember, - vid_resize, /* (C) allow resizing */ - invert_display, /* (C) invert the display */ - suppress_overscan = 0; /* (C) suppress overscans */ -int scale = 0; /* (C) screen scale factor */ -int vid_api = 0; /* (C) video renderer */ -int vid_cga_contrast = 0, /* (C) video */ - video_fullscreen = 0, /* (C) video */ - video_fullscreen_scale = 0, /* (C) video */ - video_fullscreen_first = 0, /* (C) video */ - enable_overscan = 0, /* (C) video */ - force_43 = 0; /* (C) video */ -int serial_enabled[SERIAL_MAX] = {0,0}, /* (C) enable serial ports */ - lpt_enabled = 0, /* (C) enable LPT ports */ - bugger_enabled = 0; /* (C) enable ISAbugger */ -int gfxcard = 0; /* (C) graphics/video card */ -int sound_is_float = 1, /* (C) sound uses FP values */ - GAMEBLASTER = 0, /* (C) sound option */ - GUS = 0, /* (C) sound option */ - SSI2001 = 0, /* (C) sound option */ - voodoo_enabled = 0; /* (C) video option */ -uint32_t mem_size = 0; /* (C) memory size */ -int cpu_manufacturer = 0, /* (C) cpu manufacturer */ - cpu_use_dynarec = 0, /* (C) cpu uses/needs Dyna */ - cpu = 3, /* (C) cpu type */ - enable_external_fpu = 0; /* (C) enable external FPU */ -int enable_sync = 0; /* (C) enable time sync */ - -/* Statistics. */ -extern int - mmuflush, - readlnum, - writelnum; - -int fps, framecount; /* emulator % */ - -int CPUID; -int output; -int atfullspeed; -int cpuspeed2; -int clockrate; - -int gfx_present[GFX_MAX]; /* should not be here */ - -wchar_t exe_path[1024]; /* path (dir) of executable */ -wchar_t usr_path[1024]; /* path (dir) of user data */ -wchar_t cfg_path[1024]; /* full path of config file */ -FILE *stdlog = NULL; /* file to log output to */ -int scrnsz_x = SCREEN_RES_X, /* current screen size, X */ - scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */ -int config_changed; /* config has changed */ -int romset; /* current machine ID */ -int title_update; -int64_t main_time; - - -int unscaled_size_x = SCREEN_RES_X, /* current unscaled size X */ - unscaled_size_y = SCREEN_RES_Y, /* current unscaled size Y */ - efscrnsz_y = SCREEN_RES_Y; - - -#ifndef RELEASE_BUILD -static char buff[1024]; -static int seen = 0; - -static int suppr_seen = 1; -#endif - -/* - * Log something to the logfile or stdout. - * - * To avoid excessively-large logfiles because some - * module repeatedly logs, we keep track of what is - * being logged, and catch repeating entries. - */ -void -pclog_ex(const char *fmt, va_list ap) -{ -#ifndef RELEASE_BUILD - char temp[1024]; - - if (stdlog == NULL) { - if (log_path[0] != L'\0') { - stdlog = plat_fopen(log_path, L"w"); - if (stdlog == NULL) - stdlog = stdout; - } else { - stdlog = stdout; - } - } - - vsprintf(temp, fmt, ap); - if (suppr_seen && ! strcmp(buff, temp)) { - seen++; - } else { - if (suppr_seen && seen) { - fprintf(stdlog, "*** %d repeats ***\n", seen); - } - seen = 0; - strcpy(buff, temp); - fprintf(stdlog, temp, ap); - } - - fflush(stdlog); -#endif -} - - -void -pclog_toggle_suppr(void) -{ -#ifndef RELEASE_BUILD - suppr_seen ^= 1; -#endif -} - - -/* Log something. We only do this in non-release builds. */ -void -pclog(const char *fmt, ...) -{ -#ifndef RELEASE_BUILD - va_list ap; - - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); -#endif -} - - -/* Log a fatal error, and display a UI message before exiting. */ -void -fatal(const char *fmt, ...) -{ - char temp[1024]; - va_list ap; - char *sp; - - va_start(ap, fmt); - - if (stdlog == NULL) { - if (log_path[0] != L'\0') { - stdlog = plat_fopen(log_path, L"w"); - if (stdlog == NULL) - stdlog = stdout; - } else { - stdlog = stdout; - } - } - - vsprintf(temp, fmt, ap); - fprintf(stdlog, "%s", temp); - fflush(stdlog); - va_end(ap); - - nvr_save(); - - config_save(); - - dumppic(); - dumpregs(1); - - /* Make sure the message does not have a trailing newline. */ - if ((sp = strchr(temp, '\n')) != NULL) *sp = '\0'; - - ui_msgbox(MBX_ERROR|MBX_FATAL|MBX_ANSI, temp); - - fflush(stdlog); - - exit(-1); -} - - -#ifdef ENABLE_PC_LOG -int pc_do_log = ENABLE_PC_LOG; -#endif - - -static void -pc_log(const char *format, ...) -{ -#ifdef ENABLE_PC_LOG - va_list ap; - - if (pc_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -/* - * Perform initial startup of the PC. - * - * This is the platform-indepenent part of the startup, - * where we check commandline arguments and load a - * configuration file. - */ -int -pc_init(int argc, wchar_t *argv[]) -{ - wchar_t path[2048]; - wchar_t *cfg = NULL, *p; - char temp[128]; - struct tm *info; - time_t now; - int c; - uint32_t *uid, *shwnd; - - /* Grab the executable's full path. */ - plat_get_exe_name(exe_path, sizeof(exe_path)-1); - p = plat_get_filename(exe_path); - *p = L'\0'; - - /* - * Get the current working directory. - * - * This is normally the directory from where the - * program was run. If we have been started via - * a shortcut (desktop icon), however, the CWD - * could have been set to something else. - */ - plat_getcwd(usr_path, sizeof_w(usr_path)-1); - memset(path, 0x00, sizeof(path)); - - for (c=1; c=0; c--) { - if (gfx_present[c]) { - gfxcard = c; - config_save(); - - /* This can loop if all cards now bad.. */ - goto again2; - } - } - } - - cpuspeed2 = (AT) ? 2 : 1; - atfullspeed = 0; - - random_init(); - - mem_init(); - -#ifdef USE_DYNAREC - codegen_init(); -#endif - - keyboard_init(); - joystick_init(); - video_init(); - device_init(); - - timer_reset(); - - fdd_init(); - - sound_init(); - - hdc_init(hdc_name); - - cdrom_hard_reset(); - zip_hard_reset(); - - scsi_card_init(); - - pc_full_speed(); - shadowbios = 0; - - return(1); -} - - -/* Insert keystrokes into the machine's keyboard buffer. */ -static void -pc_keyboard_send(uint8_t val) -{ - if (AT) - keyboard_at_adddata_keyboard_raw(val); - else - keyboard_send(val); -} - - -void -pc_send_ca(uint8_t sc) -{ - pc_keyboard_send(29); /* Ctrl key pressed */ - pc_keyboard_send(56); /* Alt key pressed */ - pc_keyboard_send(sc); - pc_keyboard_send(sc | 0x80); - pc_keyboard_send(184); /* Alt key released */ - pc_keyboard_send(157); /* Ctrl key released */ -} - - -/* Send the machine a Control-Alt-DEL sequence. */ -void -pc_send_cad(void) -{ - pc_send_ca(83); -} - - -/* Send the machine a Control-Alt-ESC sequence. */ -void -pc_send_cae(void) -{ - pc_send_ca(1); -} - - -void -pc_reset_hard_close(void) -{ - suppress_overscan = 0; - - nvr_save(); - - mouse_close(); - - lpt_devices_close(); - - device_close_all(); - - midi_close(); - - cdrom_close(); - - closeal(); -} - - -/* - * This is basically the spot where we start up the actual machine, - * by issuing a 'hard reset' to the entire configuration. Order is - * somewhat important here. Functions here should be named _reset - * really, as that is what they do. - */ -void -pc_reset_hard_init(void) -{ - /* - * First, we reset the modules that are not part of - * the actual machine, but which support some of the - * modules that are. - */ - - /* Reset the general machine support modules. */ - io_init(); - timer_reset(); - - device_init(); - - sound_reset(); - - /* This is needed to initialize the serial timer. */ - serial_init(); - - cdrom_hard_reset(); - zip_hard_reset(); - - /* Initialize the actual machine and its basic modules. */ - machine_init(); - - fdd_reset(); - - /* - * Once the machine has been initialized, all that remains - * should be resetting all devices set up for it, to their - * current configurations ! - * - * For now, we will call their reset functions here, but - * that will be a call to device_reset_all() later ! - */ - - /* Reset some basic devices. */ - speaker_init(); - serial_reset(); - lpt_devices_init(); - shadowbios = 0; - - /* - * This has to be after the serial initialization so that - * serial_init() doesn't break the serial mouse by resetting - * the RCR callback to NULL. - */ - mouse_reset(); - - /* Reset the video card. */ - video_reset(gfxcard); - - /* Reset the Hard Disk Controller module. */ - hdc_reset(); - - /* Reset and reconfigure the SCSI layer. */ - scsi_card_init(); - - /* Reset and reconfigure the Sound Card layer. */ - sound_card_reset(); - - /* Reset and reconfigure the Network Card layer. */ - network_reset(); - - if (joystick_type != 7) - gameport_update_joystick_type(); - - if (config_changed) { - ui_sb_update_panes(); - - config_save(); - - config_changed = 0; - } - - /* Needs the status bar... */ - if (bugger_enabled) - device_add(&bugger_device); - - /* Reset the CPU module. */ - resetx86(); - dma_reset(); - pic_reset(); - cpu_cache_int_enabled = cpu_cache_ext_enabled = 0; - - if (AT) - setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); - else - setpitclock(14318184.0); -} - - -void -pc_reset_hard(void) -{ - pc_reset_hard_close(); - - pc_reset_hard_init(); -} - - -void -pc_reset(int hard) -{ - plat_pause(1); - - plat_delay_ms(100); - - nvr_save(); - - config_save(); - - if (hard) - pc_reset_hard(); - else - pc_send_cad(); - - plat_pause(0); -} - - -void -pc_close(thread_t *ptr) -{ - int i; - - /* Wait a while so things can shut down. */ - plat_delay_ms(200); - - /* Claim the video blitter. */ - startblit(); - - /* Terminate the main thread. */ - if (ptr != NULL) { - thread_kill(ptr); - - /* Wait some more. */ - plat_delay_ms(200); - } - - nvr_save(); - - config_save(); - - plat_mouse_capture(0); - - lpt_devices_close(); - - for (i=0; i 0 && !dopause) { - /* Yes, so do one frame now. */ - start_time = plat_timer_read(); - drawits -= 10; - if (drawits > 50) - drawits = 0; - - /* Run a block of code. */ - startblit(); - clockrate = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed; - - if (is386) { -#ifdef USE_DYNAREC - if (cpu_use_dynarec) - exec386_dynarec(clockrate/100); - else -#endif - exec386(clockrate/100); - } else if (AT) { - exec386(clockrate/100); - } else { - execx86(clockrate/100); - } - - mouse_process(); - - joystick_process(); - - endblit(); - - /* Done with this frame, update statistics. */ - framecount++; - if (++framecountx >= 100) { - framecountx = 0; - - readlnum = writelnum = 0; - egareads = egawrites = 0; - mmuflush = 0; - frames = 0; - } - - if (title_update) { - mbstowcs(wmachine, machine_getname(), strlen(machine_getname())+1); - mbstowcs(wcpu, machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].name, - strlen(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].name)+1); - swprintf(temp, sizeof_w(temp), - L"%ls v%ls - %i%% - %ls - %ls - %ls", - EMU_NAME_W,EMU_VERSION_W,fps,wmachine,wcpu, - (!mouse_capture) ? plat_get_string(IDS_2077) - : (mouse_get_buttons() > 2) ? plat_get_string(IDS_2078) : plat_get_string(IDS_2079)); - - ui_window_title(temp); - - title_update = 0; - } - - /* One more frame done! */ - done++; - - /* Every 200 frames we save the machine status. */ - if (++frames >= 200 && nvr_dosave) { - nvr_save(); - nvr_dosave = 0; - frames = 0; - } - - end_time = plat_timer_read(); - main_time += (end_time - start_time); - } else { - /* Just so we dont overload the host OS. */ - plat_delay_ms(1); - } - - /* If needed, handle a screen resize. */ - if (doresize && !video_fullscreen) { - plat_resize(scrnsz_x, scrnsz_y); - - doresize = 0; - } - } - - pc_log("PC: main thread done.\n"); -} - - -/* Handler for the 1-second timer to refresh the window title. */ -void -pc_onesec(void) -{ - fps = framecount; - framecount = 0; - - title_update = 1; -} - - -void -set_screen_size(int x, int y) -{ - int owsx = scrnsz_x; - int owsy = scrnsz_y; - int temp_overscan_x = overscan_x; - int temp_overscan_y = overscan_y; - double dx, dy, dtx, dty; - - /* Make sure we keep usable values. */ -#if 0 - pc_log("SetScreenSize(%d, %d) resize=%d\n", x, y, vid_resize); -#endif - if (x < 320) x = 320; - if (y < 200) y = 200; - if (x > 2048) x = 2048; - if (y > 2048) y = 2048; - - /* Save the new values as "real" (unscaled) resolution. */ - unscaled_size_x = x; - efscrnsz_y = y; - - if (suppress_overscan) - temp_overscan_x = temp_overscan_y = 0; - - if (force_43) { - dx = (double)x; - dtx = (double)temp_overscan_x; - - dy = (double)y; - dty = (double)temp_overscan_y; - - /* Account for possible overscan. */ - if (!(video_is_ega_vga()) && (temp_overscan_y == 16)) { - /* CGA */ - dy = (((dx - dtx) / 4.0) * 3.0) + dty; - } else if (!(video_is_ega_vga()) && (temp_overscan_y < 16)) { - /* MDA/Hercules */ - dy = (x / 4.0) * 3.0; - } else { - if (enable_overscan) { - /* EGA/(S)VGA with overscan */ - dy = (((dx - dtx) / 4.0) * 3.0) + dty; - } else { - /* EGA/(S)VGA without overscan */ - dy = (x / 4.0) * 3.0; - } - } - unscaled_size_y = (int)dy; - } else { - unscaled_size_y = efscrnsz_y; - } - - switch(scale) { - case 0: /* 50% */ - scrnsz_x = (unscaled_size_x>>1); - scrnsz_y = (unscaled_size_y>>1); - break; - - case 1: /* 100% */ - scrnsz_x = unscaled_size_x; - scrnsz_y = unscaled_size_y; - break; - - case 2: /* 150% */ - scrnsz_x = ((unscaled_size_x*3)>>1); - scrnsz_y = ((unscaled_size_y*3)>>1); - break; - - case 3: /* 200% */ - scrnsz_x = (unscaled_size_x<<1); - scrnsz_y = (unscaled_size_y<<1); - break; - } - - /* If the resolution has changed, let the main thread handle it. */ - if ((owsx != scrnsz_x) || (owsy != scrnsz_y)) - doresize = 1; - else - doresize = 0; -} - - -void -set_screen_size_natural(void) -{ - set_screen_size(unscaled_size_x, unscaled_size_y); -} - - -int -get_actual_size_x(void) -{ - return(unscaled_size_x); -} - - -int -get_actual_size_y(void) -{ - return(efscrnsz_y); -} diff --git a/backup code/scsi/scsi - Cópia (2).h b/backup code/scsi/scsi - Cópia (2).h deleted file mode 100644 index 7c347b826..000000000 --- a/backup code/scsi/scsi - Cópia (2).h +++ /dev/null @@ -1,368 +0,0 @@ -/* - * 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. - * - * SCSI controller handler header. - * - * Version: @(#)scsi_h 1.0.17 2018/06/02 - * - * Authors: TheCollector1995, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 TheCollector1995. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#ifndef EMU_SCSI_H -#define EMU_SCSI_H - - -#ifdef WALTJE -#define SCSI_TIME (50 * (1 << TIMER_SHIFT)) -#else -#define SCSI_TIME (5 * 100 * (1 << TIMER_SHIFT)) -#endif - - -/* Configuration. */ -#define SCSI_ID_MAX 16 /* 16 on wide buses */ -#define SCSI_LUN_MAX 8 /* always 8 */ - - -/* SCSI commands. */ -#define GPCMD_TEST_UNIT_READY 0x00 -#define GPCMD_REZERO_UNIT 0x01 -#define GPCMD_REQUEST_SENSE 0x03 -#define GPCMD_FORMAT_UNIT 0x04 -#define GPCMD_IOMEGA_SENSE 0x06 -#define GPCMD_READ_6 0x08 -#define GPCMD_WRITE_6 0x0a -#define GPCMD_SEEK_6 0x0b -#define GPCMD_IOMEGA_SET_PROTECTION_MODE 0x0c -#define GPCMD_IOMEGA_EJECT 0x0d /* ATAPI only? */ -#define GPCMD_INQUIRY 0x12 -#define GPCMD_VERIFY_6 0x13 -#define GPCMD_MODE_SELECT_6 0x15 -#define GPCMD_SCSI_RESERVE 0x16 -#define GPCMD_SCSI_RELEASE 0x17 -#define GPCMD_MODE_SENSE_6 0x1a -#define GPCMD_START_STOP_UNIT 0x1b -#define GPCMD_SEND_DIAGNOSTIC 0x1d -#define GPCMD_PREVENT_REMOVAL 0x1e -#define GPCMD_READ_FORMAT_CAPACITIES 0x23 -#define GPCMD_READ_CDROM_CAPACITY 0x25 -#define GPCMD_READ_10 0x28 -#define GPCMD_WRITE_10 0x2a -#define GPCMD_SEEK_10 0x2b -#define GPCMD_WRITE_AND_VERIFY_10 0x2e -#define GPCMD_VERIFY_10 0x2f -#define GPCMD_READ_BUFFER 0x3c -#define GPCMD_WRITE_SAME_10 0x41 -#define GPCMD_READ_SUBCHANNEL 0x42 -#define GPCMD_READ_TOC_PMA_ATIP 0x43 -#define GPCMD_READ_HEADER 0x44 -#define GPCMD_PLAY_AUDIO_10 0x45 -#define GPCMD_GET_CONFIGURATION 0x46 -#define GPCMD_PLAY_AUDIO_MSF 0x47 -#define GPCMD_PLAY_AUDIO_TRACK_INDEX 0x48 -#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a -#define GPCMD_PAUSE_RESUME 0x4b -#define GPCMD_STOP_PLAY_SCAN 0x4e -#define GPCMD_READ_DISC_INFORMATION 0x51 -#define GPCMD_READ_TRACK_INFORMATION 0x52 -#define GPCMD_MODE_SELECT_10 0x55 -#define GPCMD_MODE_SENSE_10 0x5a -#define GPCMD_PLAY_AUDIO_12 0xa5 -#define GPCMD_READ_12 0xa8 -#define GPCMD_WRITE_12 0xaa -#define GPCMD_READ_DVD_STRUCTURE 0xad /* For reading. */ -#define GPCMD_WRITE_AND_VERIFY_12 0xae -#define GPCMD_VERIFY_12 0xaf -#define GPCMD_PLAY_CD_OLD 0xb4 -#define GPCMD_READ_CD_OLD 0xb8 -#define GPCMD_READ_CD_MSF 0xb9 -#define GPCMD_SCAN 0xba -#define GPCMD_SET_SPEED 0xbb -#define GPCMD_PLAY_CD 0xbc -#define GPCMD_MECHANISM_STATUS 0xbd -#define GPCMD_READ_CD 0xbe -#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to PCem. */ -#define GPCMD_PAUSE_RESUME_ALT 0xc2 -#define GPCMD_SCAN_ALT 0xcd /* Should be equivalent to 0xba */ -#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */ - -/* Mode page codes for mode sense/set */ -#define GPMODE_R_W_ERROR_PAGE 0x01 -#define GPMODE_CDROM_PAGE 0x0d -#define GPMODE_CDROM_AUDIO_PAGE 0x0e -#define GPMODE_CAPABILITIES_PAGE 0x2a -#define GPMODE_ALL_PAGES 0x3f - -/* Mode page codes for presence */ -#define GPMODEP_R_W_ERROR_PAGE 0x0000000000000002LL -#define GPMODEP_CDROM_PAGE 0x0000000000002000LL -#define GPMODEP_CDROM_AUDIO_PAGE 0x0000000000004000LL -#define GPMODEP_CAPABILITIES_PAGE 0x0000040000000000LL -#define GPMODEP_ALL_PAGES 0x8000000000000000LL - -/* SCSI Status Codes */ -#define SCSI_STATUS_OK 0 -#define SCSI_STATUS_CHECK_CONDITION 2 - -/* SCSI Sense Keys */ -#define SENSE_NONE 0 -#define SENSE_NOT_READY 2 -#define SENSE_ILLEGAL_REQUEST 5 -#define SENSE_UNIT_ATTENTION 6 - -/* SCSI Additional Sense Codes */ -#define ASC_AUDIO_PLAY_OPERATION 0x00 -#define ASC_NOT_READY 0x04 -#define ASC_ILLEGAL_OPCODE 0x20 -#define ASC_LBA_OUT_OF_RANGE 0x21 -#define ASC_INV_FIELD_IN_CMD_PACKET 0x24 -#define ASC_INV_LUN 0x25 -#define ASC_INV_FIELD_IN_PARAMETER_LIST 0x26 -#define ASC_WRITE_PROTECTED 0x27 -#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 -#define ASC_CAPACITY_DATA_CHANGED 0x2A -#define ASC_INCOMPATIBLE_FORMAT 0x30 -#define ASC_MEDIUM_NOT_PRESENT 0x3a -#define ASC_DATA_PHASE_ERROR 0x4b -#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK 0x64 - -#define ASCQ_UNIT_IN_PROCESS_OF_BECOMING_READY 0x01 -#define ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02 -#define ASCQ_CAPACITY_DATA_CHANGED 0x09 -#define ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS 0x11 -#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12 -#define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13 - -/* Tell RISC OS that we have a 4x CD-ROM drive (600kb/sec data, 706kb/sec raw). - Not that it means anything */ -#define CDROM_SPEED 706 /* 0x2C2 */ - -#define BUFFER_SIZE (256*1024) - -#define RW_DELAY (TIMER_USEC * 500) - -/* Some generally useful CD-ROM information */ -#define CD_MINS 75 /* max. minutes per CD */ -#define CD_SECS 60 /* seconds per minute */ -#define CD_FRAMES 75 /* frames per second */ -#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */ -#define CD_MAX_BYTES (CD_MINS * CD_SECS * CD_FRAMES * CD_FRAMESIZE) -#define CD_MAX_SECTORS (CD_MAX_BYTES / 512) - -/* Event notification classes for GET EVENT STATUS NOTIFICATION */ -#define GESN_NO_EVENTS 0 -#define GESN_OPERATIONAL_CHANGE 1 -#define GESN_POWER_MANAGEMENT 2 -#define GESN_EXTERNAL_REQUEST 3 -#define GESN_MEDIA 4 -#define GESN_MULTIPLE_HOSTS 5 -#define GESN_DEVICE_BUSY 6 - -/* Event codes for MEDIA event status notification */ -#define MEC_NO_CHANGE 0 -#define MEC_EJECT_REQUESTED 1 -#define MEC_NEW_MEDIA 2 -#define MEC_MEDIA_REMOVAL 3 /* only for media changers */ -#define MEC_MEDIA_CHANGED 4 /* only for media changers */ -#define MEC_BG_FORMAT_COMPLETED 5 /* MRW or DVD+RW b/g format completed */ -#define MEC_BG_FORMAT_RESTARTED 6 /* MRW or DVD+RW b/g format restarted */ -#define MS_TRAY_OPEN 1 -#define MS_MEDIA_PRESENT 2 - -/* - * The MMC values are not IDE specific and might need to be moved - * to a common header if they are also needed for the SCSI emulation - */ - -/* Profile list from MMC-6 revision 1 table 91 */ -#define MMC_PROFILE_NONE 0x0000 -#define MMC_PROFILE_CD_ROM 0x0008 -#define MMC_PROFILE_CD_R 0x0009 -#define MMC_PROFILE_CD_RW 0x000A -#define MMC_PROFILE_DVD_ROM 0x0010 -#define MMC_PROFILE_DVD_R_SR 0x0011 -#define MMC_PROFILE_DVD_RAM 0x0012 -#define MMC_PROFILE_DVD_RW_RO 0x0013 -#define MMC_PROFILE_DVD_RW_SR 0x0014 -#define MMC_PROFILE_DVD_R_DL_SR 0x0015 -#define MMC_PROFILE_DVD_R_DL_JR 0x0016 -#define MMC_PROFILE_DVD_RW_DL 0x0017 -#define MMC_PROFILE_DVD_DDR 0x0018 -#define MMC_PROFILE_DVD_PLUS_RW 0x001A -#define MMC_PROFILE_DVD_PLUS_R 0x001B -#define MMC_PROFILE_DVD_PLUS_RW_DL 0x002A -#define MMC_PROFILE_DVD_PLUS_R_DL 0x002B -#define MMC_PROFILE_BD_ROM 0x0040 -#define MMC_PROFILE_BD_R_SRM 0x0041 -#define MMC_PROFILE_BD_R_RRM 0x0042 -#define MMC_PROFILE_BD_RE 0x0043 -#define MMC_PROFILE_HDDVD_ROM 0x0050 -#define MMC_PROFILE_HDDVD_R 0x0051 -#define MMC_PROFILE_HDDVD_RAM 0x0052 -#define MMC_PROFILE_HDDVD_RW 0x0053 -#define MMC_PROFILE_HDDVD_R_DL 0x0058 -#define MMC_PROFILE_HDDVD_RW_DL 0x005A -#define MMC_PROFILE_INVALID 0xFFFF - -#define SCSI_ONLY 32 -#define ATAPI_ONLY 16 -#define IMPLEMENTED 8 -#define NONDATA 4 -#define CHECK_READY 2 -#define ALLOW_UA 1 - - -extern uint8_t SCSICommandTable[0x100]; -extern uint8_t mode_sense_pages[0x40]; -extern int readcdmode; - -/* Mode sense/select stuff. */ -extern uint8_t mode_pages_in[256][256]; -extern uint8_t page_flags[256]; -extern uint8_t prefix_len; -extern uint8_t page_current; -#define PAGE_CHANGEABLE 1 -#define PAGE_CHANGED 2 - -struct _scsisense_ { - uint8_t SenseBuffer[18]; - uint8_t SenseLength; - uint8_t UnitAttention; - uint8_t SenseKey; - uint8_t Asc; - uint8_t Ascq; -} SCSISense; - -extern int cd_status; -extern int prev_status; - -enum { - SCSI_NONE = 0, - SCSI_NULL, - SCSI_DISK, - SCSI_CDROM, - SCSI_ZIP -}; - -#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) - -#define MSG_COMMAND_COMPLETE 0x00 - -#define BUS_DBP 0x01 -#define BUS_SEL 0x02 -#define BUS_IO 0x04 -#define BUS_CD 0x08 -#define BUS_MSG 0x10 -#define BUS_REQ 0x20 -#define BUS_BSY 0x40 -#define BUS_RST 0x80 -#define BUS_ACK 0x200 -#define BUS_ATN 0x200 -#define BUS_ARB 0x8000 -#define BUS_SETDATA(val) ((uint32_t)val << 16) -#define BUS_GETDATA(val) ((val >> 16) & 0xff) -#define BUS_DATAMASK 0xff0000 - -#define BUS_IDLE (1 << 31) - -#define SCSI_PHASE_DATA_OUT 0 -#define SCSI_PHASE_DATA_IN BUS_IO -#define SCSI_PHASE_COMMAND BUS_CD -#define SCSI_PHASE_STATUS (BUS_CD | BUS_IO) -#define SCSI_PHASE_MESSAGE_OUT (BUS_MSG | BUS_CD) -#define SCSI_PHASE_MESSAGE_IN (BUS_MSG | BUS_CD | BUS_IO) - -typedef struct { - uint8_t *CmdBuffer; - int LunType; - int32_t BufferLength; - uint8_t Status; - uint8_t Phase; -} scsi_device_t; - - -extern scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX]; - -extern void SCSIReset(uint8_t id, uint8_t lun); - -extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type); -extern int cdrom_LBAtoMSF_accurate(void); - -extern int mode_select_init(uint8_t command, uint16_t pl_length, uint8_t do_save); -extern int mode_select_terminate(int force); -extern int mode_select_write(uint8_t val); - -extern int scsi_card_current; - -extern int scsi_card_available(int card); -extern char *scsi_card_getname(int card); -#ifdef EMU_DEVICE_H -extern const device_t *scsi_card_getdevice(int card); -#endif -extern int scsi_card_has_config(int card); -extern char *scsi_card_get_internal_name(int card); -extern int scsi_card_get_from_internal_name(char *s); -extern void scsi_mutex(uint8_t start); -extern void scsi_card_init(void); - - -#pragma pack(push,1) -typedef struct { - uint8_t hi; - uint8_t mid; - uint8_t lo; -} addr24; -#pragma pack(pop) - -#define ADDR_TO_U32(x) (((x).hi<<16)|((x).mid<<8)|((x).lo&0xFF)) -#define U32_TO_ADDR(a,x) do {(a).hi=(x)>>16;(a).mid=(x)>>8;(a).lo=(x)&0xFF;}while(0) - - -/* - * - * Scatter/Gather Segment List Definitions - * - * Adapter limits - */ -#define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */ - -#pragma pack(push,1) -typedef struct { - uint32_t Segment; - uint32_t SegmentPointer; -} SGE32; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - addr24 Segment; - addr24 SegmentPointer; -} SGE; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - uint8_t pages[0x40][0x40]; -} mode_sense_pages_t; -#pragma pack(pop) - - -#define MODE_SELECT_PHASE_IDLE 0 -#define MODE_SELECT_PHASE_HEADER 1 -#define MODE_SELECT_PHASE_BLOCK_DESC 2 -#define MODE_SELECT_PHASE_PAGE_HEADER 3 -#define MODE_SELECT_PHASE_PAGE 4 - -#endif /*EMU_SCSI_H*/ - -extern void scsi_mutex_wait(uint8_t wait); diff --git a/backup code/scsi/scsi - Cópia.c b/backup code/scsi/scsi - Cópia.c deleted file mode 100644 index ff36f0b8b..000000000 --- a/backup code/scsi/scsi - Cópia.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * 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. - * - * Handling of the SCSI controllers. - * - * Version: @(#)scsi.c 1.0.19 2018/04/29 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * TheCollector1995, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../disk/hdc.h" -#include "../disk/zip.h" -#include "../plat.h" -#include "scsi.h" -#include "../cdrom/cdrom.h" -#include "scsi_device.h" -#include "scsi_aha154x.h" -#include "scsi_buslogic.h" -#include "scsi_ncr5380.h" -#include "scsi_ncr53c810.h" -#ifdef WALTJE -# include "scsi_wd33c93.h" -#endif -#include "scsi_x54x.h" - - -scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX]; -// uint8_t SCSIPhase = 0xff; -// uint8_t SCSIStatus = SCSI_STATUS_OK; -char scsi_fn[SCSI_NUM][512]; -uint16_t scsi_hd_location[SCSI_NUM]; - -int scsi_card_current = 0; -int scsi_card_last = 0; - -uint32_t SCSI_BufferLength; -static volatile -mutex_t *scsiMutex; - - -typedef const struct { - const char *name; - const char *internal_name; - const device_t *device; -} SCSI_CARD; - - -static SCSI_CARD scsi_cards[] = { - { "None", "none", NULL, }, - { "[ISA] Adaptec AHA-1540B","aha1540b", &aha1540b_device, }, - { "[ISA] Adaptec AHA-1542C","aha1542c", &aha1542c_device, }, - { "[ISA] Adaptec AHA-1542CF","aha1542cf", &aha1542cf_device, }, - { "[ISA] BusLogic BT-542BH","bt542bh", &buslogic_device, }, - { "[ISA] BusLogic BT-545S", "bt545s", &buslogic_545s_device,}, - { "[ISA] Longshine LCS-6821N","lcs6821n", &scsi_lcs6821n_device,}, - { "[ISA] Ranco RT1000B", "rt1000b", &scsi_rt1000b_device, }, - { "[ISA] Trantor T130B", "t130b", &scsi_t130b_device, }, - { "[ISA] Sumo SCSI-AT", "scsiat", &scsi_scsiat_device, }, -#ifdef WALTJE - { "[ISA] Generic WDC33C93", "wd33c93", &scsi_wd33c93_device, }, -#endif - { "[MCA] Adaptec AHA-1640", "aha1640", &aha1640_device, }, - { "[MCA] BusLogic BT-640A", "bt640a", &buslogic_640a_device,}, - { "[PCI] BusLogic BT-958D", "bt958d", &buslogic_pci_device, }, - { "[PCI] NCR 53C810", "ncr53c810", &ncr53c810_pci_device,}, - { "[VLB] BusLogic BT-445S", "bt445s", &buslogic_445s_device,}, - { "", "", NULL, }, -}; - - -#ifdef ENABLE_SCSI_LOG -int scsi_do_log = ENABLE_SCSI_LOG; -#endif - - -static void -scsi_log(const char *fmt, ...) -{ -#ifdef ENABLE_SCSI_LOG - va_list ap; - - if (scsi_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -int scsi_card_available(int card) -{ - if (scsi_cards[card].device) - return(device_available(scsi_cards[card].device)); - - return(1); -} - - -char *scsi_card_getname(int card) -{ - return((char *) scsi_cards[card].name); -} - - -const device_t *scsi_card_getdevice(int card) -{ - return(scsi_cards[card].device); -} - - -int scsi_card_has_config(int card) -{ - if (! scsi_cards[card].device) return(0); - - return(scsi_cards[card].device->config ? 1 : 0); -} - - -char *scsi_card_get_internal_name(int card) -{ - return((char *) scsi_cards[card].internal_name); -} - - -int scsi_card_get_from_internal_name(char *s) -{ - int c = 0; - - while (strlen((char *) scsi_cards[c].internal_name)) { - if (!strcmp((char *) scsi_cards[c].internal_name, s)) - return(c); - c++; - } - - return(0); -} - - -void scsi_mutex(uint8_t start) -{ - if (start) - scsiMutex = thread_create_mutex(L"86Box.SCSIMutex"); - else - thread_close_mutex((mutex_t *) scsiMutex); -} - - -void scsi_card_init(void) -{ - int i, j; - - if (!scsi_cards[scsi_card_current].device) - return; - - scsi_log("Building SCSI hard disk map...\n"); - build_scsi_hd_map(); - scsi_log("Building SCSI CD-ROM map...\n"); - build_scsi_cdrom_map(); - scsi_log("Building SCSI ZIP map...\n"); - build_scsi_zip_map(); - - for (i=0; i - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 TheCollector1995. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#ifndef EMU_SCSI_H -#define EMU_SCSI_H - - -#ifdef WALTJE -#define SCSI_TIME (50 * (1 << TIMER_SHIFT)) -#else -#define SCSI_TIME (5 * 100 * (1 << TIMER_SHIFT)) -#endif - - -/* Configuration. */ -#define SCSI_ID_MAX 16 /* 16 on wide buses */ -#define SCSI_LUN_MAX 8 /* always 8 */ - - -/* SCSI commands. */ -#define GPCMD_TEST_UNIT_READY 0x00 -#define GPCMD_REZERO_UNIT 0x01 -#define GPCMD_REQUEST_SENSE 0x03 -#define GPCMD_FORMAT_UNIT 0x04 -#define GPCMD_IOMEGA_SENSE 0x06 -#define GPCMD_READ_6 0x08 -#define GPCMD_WRITE_6 0x0a -#define GPCMD_SEEK_6 0x0b -#define GPCMD_IOMEGA_SET_PROTECTION_MODE 0x0c -#define GPCMD_IOMEGA_EJECT 0x0d /* ATAPI only? */ -#define GPCMD_INQUIRY 0x12 -#define GPCMD_VERIFY_6 0x13 -#define GPCMD_MODE_SELECT_6 0x15 -#define GPCMD_SCSI_RESERVE 0x16 -#define GPCMD_SCSI_RELEASE 0x17 -#define GPCMD_MODE_SENSE_6 0x1a -#define GPCMD_START_STOP_UNIT 0x1b -#define GPCMD_SEND_DIAGNOSTIC 0x1d -#define GPCMD_PREVENT_REMOVAL 0x1e -#define GPCMD_READ_FORMAT_CAPACITIES 0x23 -#define GPCMD_READ_CDROM_CAPACITY 0x25 -#define GPCMD_READ_10 0x28 -#define GPCMD_WRITE_10 0x2a -#define GPCMD_SEEK_10 0x2b -#define GPCMD_WRITE_AND_VERIFY_10 0x2e -#define GPCMD_VERIFY_10 0x2f -#define GPCMD_READ_BUFFER 0x3c -#define GPCMD_WRITE_SAME_10 0x41 -#define GPCMD_READ_SUBCHANNEL 0x42 -#define GPCMD_READ_TOC_PMA_ATIP 0x43 -#define GPCMD_READ_HEADER 0x44 -#define GPCMD_PLAY_AUDIO_10 0x45 -#define GPCMD_GET_CONFIGURATION 0x46 -#define GPCMD_PLAY_AUDIO_MSF 0x47 -#define GPCMD_PLAY_AUDIO_TRACK_INDEX 0x48 -#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a -#define GPCMD_PAUSE_RESUME 0x4b -#define GPCMD_STOP_PLAY_SCAN 0x4e -#define GPCMD_READ_DISC_INFORMATION 0x51 -#define GPCMD_READ_TRACK_INFORMATION 0x52 -#define GPCMD_MODE_SELECT_10 0x55 -#define GPCMD_MODE_SENSE_10 0x5a -#define GPCMD_PLAY_AUDIO_12 0xa5 -#define GPCMD_READ_12 0xa8 -#define GPCMD_WRITE_12 0xaa -#define GPCMD_READ_DVD_STRUCTURE 0xad /* For reading. */ -#define GPCMD_WRITE_AND_VERIFY_12 0xae -#define GPCMD_VERIFY_12 0xaf -#define GPCMD_PLAY_CD_OLD 0xb4 -#define GPCMD_READ_CD_OLD 0xb8 -#define GPCMD_READ_CD_MSF 0xb9 -#define GPCMD_SCAN 0xba -#define GPCMD_SET_SPEED 0xbb -#define GPCMD_PLAY_CD 0xbc -#define GPCMD_MECHANISM_STATUS 0xbd -#define GPCMD_READ_CD 0xbe -#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to PCem. */ -#define GPCMD_PAUSE_RESUME_ALT 0xc2 -#define GPCMD_SCAN_ALT 0xcd /* Should be equivalent to 0xba */ -#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */ - -/* Mode page codes for mode sense/set */ -#define GPMODE_R_W_ERROR_PAGE 0x01 -#define GPMODE_CDROM_PAGE 0x0d -#define GPMODE_CDROM_AUDIO_PAGE 0x0e -#define GPMODE_CAPABILITIES_PAGE 0x2a -#define GPMODE_ALL_PAGES 0x3f - -/* Mode page codes for presence */ -#define GPMODEP_R_W_ERROR_PAGE 0x0000000000000002LL -#define GPMODEP_CDROM_PAGE 0x0000000000002000LL -#define GPMODEP_CDROM_AUDIO_PAGE 0x0000000000004000LL -#define GPMODEP_CAPABILITIES_PAGE 0x0000040000000000LL -#define GPMODEP_ALL_PAGES 0x8000000000000000LL - -/* SCSI Status Codes */ -#define SCSI_STATUS_OK 0 -#define SCSI_STATUS_CHECK_CONDITION 2 - -/* SCSI Sense Keys */ -#define SENSE_NONE 0 -#define SENSE_NOT_READY 2 -#define SENSE_ILLEGAL_REQUEST 5 -#define SENSE_UNIT_ATTENTION 6 - -/* SCSI Additional Sense Codes */ -#define ASC_AUDIO_PLAY_OPERATION 0x00 -#define ASC_NOT_READY 0x04 -#define ASC_ILLEGAL_OPCODE 0x20 -#define ASC_LBA_OUT_OF_RANGE 0x21 -#define ASC_INV_FIELD_IN_CMD_PACKET 0x24 -#define ASC_INV_LUN 0x25 -#define ASC_INV_FIELD_IN_PARAMETER_LIST 0x26 -#define ASC_WRITE_PROTECTED 0x27 -#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 -#define ASC_CAPACITY_DATA_CHANGED 0x2A -#define ASC_INCOMPATIBLE_FORMAT 0x30 -#define ASC_MEDIUM_NOT_PRESENT 0x3a -#define ASC_DATA_PHASE_ERROR 0x4b -#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK 0x64 - -#define ASCQ_UNIT_IN_PROCESS_OF_BECOMING_READY 0x01 -#define ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02 -#define ASCQ_CAPACITY_DATA_CHANGED 0x09 -#define ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS 0x11 -#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12 -#define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13 - -/* Tell RISC OS that we have a 4x CD-ROM drive (600kb/sec data, 706kb/sec raw). - Not that it means anything */ -#define CDROM_SPEED 706 /* 0x2C2 */ - -#define BUFFER_SIZE (256*1024) - -#define RW_DELAY (TIMER_USEC * 500) - -/* Some generally useful CD-ROM information */ -#define CD_MINS 75 /* max. minutes per CD */ -#define CD_SECS 60 /* seconds per minute */ -#define CD_FRAMES 75 /* frames per second */ -#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */ -#define CD_MAX_BYTES (CD_MINS * CD_SECS * CD_FRAMES * CD_FRAMESIZE) -#define CD_MAX_SECTORS (CD_MAX_BYTES / 512) - -/* Event notification classes for GET EVENT STATUS NOTIFICATION */ -#define GESN_NO_EVENTS 0 -#define GESN_OPERATIONAL_CHANGE 1 -#define GESN_POWER_MANAGEMENT 2 -#define GESN_EXTERNAL_REQUEST 3 -#define GESN_MEDIA 4 -#define GESN_MULTIPLE_HOSTS 5 -#define GESN_DEVICE_BUSY 6 - -/* Event codes for MEDIA event status notification */ -#define MEC_NO_CHANGE 0 -#define MEC_EJECT_REQUESTED 1 -#define MEC_NEW_MEDIA 2 -#define MEC_MEDIA_REMOVAL 3 /* only for media changers */ -#define MEC_MEDIA_CHANGED 4 /* only for media changers */ -#define MEC_BG_FORMAT_COMPLETED 5 /* MRW or DVD+RW b/g format completed */ -#define MEC_BG_FORMAT_RESTARTED 6 /* MRW or DVD+RW b/g format restarted */ -#define MS_TRAY_OPEN 1 -#define MS_MEDIA_PRESENT 2 - -/* - * The MMC values are not IDE specific and might need to be moved - * to a common header if they are also needed for the SCSI emulation - */ - -/* Profile list from MMC-6 revision 1 table 91 */ -#define MMC_PROFILE_NONE 0x0000 -#define MMC_PROFILE_CD_ROM 0x0008 -#define MMC_PROFILE_CD_R 0x0009 -#define MMC_PROFILE_CD_RW 0x000A -#define MMC_PROFILE_DVD_ROM 0x0010 -#define MMC_PROFILE_DVD_R_SR 0x0011 -#define MMC_PROFILE_DVD_RAM 0x0012 -#define MMC_PROFILE_DVD_RW_RO 0x0013 -#define MMC_PROFILE_DVD_RW_SR 0x0014 -#define MMC_PROFILE_DVD_R_DL_SR 0x0015 -#define MMC_PROFILE_DVD_R_DL_JR 0x0016 -#define MMC_PROFILE_DVD_RW_DL 0x0017 -#define MMC_PROFILE_DVD_DDR 0x0018 -#define MMC_PROFILE_DVD_PLUS_RW 0x001A -#define MMC_PROFILE_DVD_PLUS_R 0x001B -#define MMC_PROFILE_DVD_PLUS_RW_DL 0x002A -#define MMC_PROFILE_DVD_PLUS_R_DL 0x002B -#define MMC_PROFILE_BD_ROM 0x0040 -#define MMC_PROFILE_BD_R_SRM 0x0041 -#define MMC_PROFILE_BD_R_RRM 0x0042 -#define MMC_PROFILE_BD_RE 0x0043 -#define MMC_PROFILE_HDDVD_ROM 0x0050 -#define MMC_PROFILE_HDDVD_R 0x0051 -#define MMC_PROFILE_HDDVD_RAM 0x0052 -#define MMC_PROFILE_HDDVD_RW 0x0053 -#define MMC_PROFILE_HDDVD_R_DL 0x0058 -#define MMC_PROFILE_HDDVD_RW_DL 0x005A -#define MMC_PROFILE_INVALID 0xFFFF - -#define SCSI_ONLY 32 -#define ATAPI_ONLY 16 -#define IMPLEMENTED 8 -#define NONDATA 4 -#define CHECK_READY 2 -#define ALLOW_UA 1 - - -extern uint8_t SCSICommandTable[0x100]; -extern uint8_t mode_sense_pages[0x40]; -extern int readcdmode; - -/* Mode sense/select stuff. */ -extern uint8_t mode_pages_in[256][256]; -extern uint8_t page_flags[256]; -extern uint8_t prefix_len; -extern uint8_t page_current; -#define PAGE_CHANGEABLE 1 -#define PAGE_CHANGED 2 - -struct _scsisense_ { - uint8_t SenseBuffer[18]; - uint8_t SenseLength; - uint8_t UnitAttention; - uint8_t SenseKey; - uint8_t Asc; - uint8_t Ascq; -} SCSISense; - -extern int cd_status; -extern int prev_status; - -enum { - SCSI_NONE = 0, - SCSI_DISK, - SCSI_CDROM, - SCSI_ZIP -}; - -#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) - -#define MSG_COMMAND_COMPLETE 0x00 - -#define BUS_DBP 0x01 -#define BUS_SEL 0x02 -#define BUS_IO 0x04 -#define BUS_CD 0x08 -#define BUS_MSG 0x10 -#define BUS_REQ 0x20 -#define BUS_BSY 0x40 -#define BUS_RST 0x80 -#define BUS_ACK 0x200 -#define BUS_ATN 0x200 -#define BUS_ARB 0x8000 -#define BUS_SETDATA(val) ((uint32_t)val << 16) -#define BUS_GETDATA(val) ((val >> 16) & 0xff) -#define BUS_DATAMASK 0xff0000 - -#define BUS_IDLE (1 << 31) - -#define SCSI_PHASE_DATA_OUT 0 -#define SCSI_PHASE_DATA_IN BUS_IO -#define SCSI_PHASE_COMMAND BUS_CD -#define SCSI_PHASE_STATUS (BUS_CD | BUS_IO) -#define SCSI_PHASE_MESSAGE_OUT (BUS_MSG | BUS_CD) -#define SCSI_PHASE_MESSAGE_IN (BUS_MSG | BUS_CD | BUS_IO) - -typedef struct { - uint8_t *CmdBuffer; - int LunType; - int32_t BufferLength; - uint8_t Status; - uint8_t Phase; -} scsi_device_t; - - -extern scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX]; - -extern void SCSIReset(uint8_t id, uint8_t lun); - -extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type); -extern int cdrom_LBAtoMSF_accurate(void); - -extern int mode_select_init(uint8_t command, uint16_t pl_length, uint8_t do_save); -extern int mode_select_terminate(int force); -extern int mode_select_write(uint8_t val); - -extern int scsi_card_current; - -extern int scsi_card_available(int card); -extern char *scsi_card_getname(int card); -#ifdef EMU_DEVICE_H -extern const device_t *scsi_card_getdevice(int card); -#endif -extern int scsi_card_has_config(int card); -extern char *scsi_card_get_internal_name(int card); -extern int scsi_card_get_from_internal_name(char *s); -extern void scsi_mutex(uint8_t start); -extern void scsi_card_init(void); - -extern uint8_t scsi_hard_disks[16][8]; - -extern int scsi_hd_err_stat_to_scsi(uint8_t id); -extern int scsi_hd_phase_to_scsi(uint8_t id); -extern int find_hdc_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); -extern void build_scsi_hd_map(void); -extern void scsi_hd_reset(uint8_t id); -extern void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length); -extern void scsi_hd_command(uint8_t id, uint8_t *cdb); -extern void scsi_hd_callback(uint8_t id); - - -#pragma pack(push,1) -typedef struct { - uint8_t hi; - uint8_t mid; - uint8_t lo; -} addr24; -#pragma pack(pop) - -#define ADDR_TO_U32(x) (((x).hi<<16)|((x).mid<<8)|((x).lo&0xFF)) -#define U32_TO_ADDR(a,x) do {(a).hi=(x)>>16;(a).mid=(x)>>8;(a).lo=(x)&0xFF;}while(0) - - -/* - * - * Scatter/Gather Segment List Definitions - * - * Adapter limits - */ -#define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */ - -#pragma pack(push,1) -typedef struct { - uint32_t Segment; - uint32_t SegmentPointer; -} SGE32; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - addr24 Segment; - addr24 SegmentPointer; -} SGE; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - uint8_t pages[0x40][0x40]; -} mode_sense_pages_t; -#pragma pack(pop) - - -#define MODE_SELECT_PHASE_IDLE 0 -#define MODE_SELECT_PHASE_HEADER 1 -#define MODE_SELECT_PHASE_BLOCK_DESC 2 -#define MODE_SELECT_PHASE_PAGE_HEADER 3 -#define MODE_SELECT_PHASE_PAGE 4 - -#endif /*EMU_SCSI_H*/ - -extern void scsi_mutex_wait(uint8_t wait); diff --git a/backup code/scsi/scsi_device - Cópia (2).c b/backup code/scsi/scsi_device - Cópia (2).c deleted file mode 100644 index 258974b43..000000000 --- a/backup code/scsi/scsi_device - Cópia (2).c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * 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. - * - * The generic SCSI device command handler. - * - * Version: @(#)scsi_device.c 1.0.17 2018/06/02 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../disk/hdd.h" -#include "scsi.h" -#include "scsi_device.h" -#include "../cdrom/cdrom.h" -#include "../disk/zip.h" -#include "scsi_disk.h" - - -static uint8_t -scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb) -{ - switch(lun_type) { - case SCSI_NULL: - scsi_null_command(cdb); - return scsi_null_err_stat_to_scsi(); - case SCSI_DISK: - scsi_disk_command(scsi_disk[id], cdb); - return scsi_disk_err_stat_to_scsi(scsi_disk[id]); - case SCSI_CDROM: - cdrom_command(cdrom[id], cdb); - return cdrom_CDROM_PHASE_to_scsi(cdrom[id]); - case SCSI_ZIP: - zip_command(zip[id], cdb); - return zip_ZIP_PHASE_to_scsi(zip[id]); - default: - return SCSI_STATUS_CHECK_CONDITION; - } -} - - -static void scsi_device_target_phase_callback(int lun_type, uint8_t id) -{ - switch(lun_type) { - case SCSI_NULL: - scsi_null_callback(); - break; - case SCSI_DISK: - scsi_disk_callback(scsi_disk[id]); - break; - case SCSI_CDROM: - cdrom_phase_callback(cdrom[id]); - break; - case SCSI_ZIP: - zip_phase_callback(zip[id]); - break; - } - return; -} - - -static int scsi_device_target_err_stat_to_scsi(int lun_type, uint8_t id) -{ - switch(lun_type) { - case SCSI_NULL: - return scsi_null_err_stat_to_scsi(); - case SCSI_DISK: - return scsi_disk_err_stat_to_scsi(scsi_disk[id]); - case SCSI_CDROM: - return cdrom_CDROM_PHASE_to_scsi(cdrom[id]); - case SCSI_ZIP: - return zip_ZIP_PHASE_to_scsi(zip[id]); - default: - return SCSI_STATUS_CHECK_CONDITION; - } -} - - -static void scsi_device_target_save_cdb_byte(int lun_type, uint8_t id, uint8_t cdb_byte) -{ - switch(lun_type) { - case SCSI_DISK: - scsi_disk[id]->request_length = cdb_byte; - break; - case SCSI_CDROM: - cdrom[id]->request_length = cdb_byte; - break; - case SCSI_ZIP: - zip[id]->request_length = cdb_byte; - break; - } - return; -} - - -int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - return scsi_disk[id]->callback; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id]->callback; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - return zip[id]->callback; - break; - default: - return -1LL; - break; - } -} - - -uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - return scsi_disk[id]->sense; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id]->sense; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - return zip[id]->sense; - break; - default: - return scsi_null_device_sense; - break; - } -} - - -void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffer, uint8_t alloc_length) -{ - uint8_t main_lun_type = SCSIDevices[scsi_id][0].LunType; - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - if ((main_lun_type != SCSI_NONE) && (lun_type == SCSI_NONE) && scsi_lun) - lun_type = SCSI_NULL; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_NULL: - scsi_null_request_sense_for_scsi(buffer, alloc_length); - break; - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - scsi_disk_request_sense_for_scsi(scsi_disk[id], buffer, alloc_length); - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - cdrom_request_sense_for_scsi(cdrom[id], buffer, alloc_length); - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - zip_request_sense_for_scsi(zip[id], buffer, alloc_length); - break; - default: - memcpy(buffer, scsi_null_device_sense, alloc_length); - break; - } -} - - -void scsi_device_reset(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t main_lun_type = SCSIDevices[scsi_id][0].LunType; - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - if ((main_lun_type != SCSI_NONE) && (lun_type == SCSI_NONE) && scsi_lun) - lun_type = SCSI_NULL; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_NULL: - scsi_null_device_sense[2] = scsi_null_device_sense[12] = - scsi_null_device_sense[13] = 0x00; - break; - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - scsi_disk_reset(scsi_disk[id]); - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - cdrom_reset(cdrom[id]); - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - zip_reset(zip[id]); - break; - } -} - - -void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uint8_t *rmb) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - switch (lun_type) - { - case SCSI_DISK: - *type = *rmb = 0x00; - break; - case SCSI_CDROM: - *type = 0x05; - *rmb = 0x80; - break; - case SCSI_ZIP: - *type = 0x00; - *rmb = 0x80; - break; - default: - *type = *rmb = 0xff; - break; - } -} - - -int scsi_device_read_capacity(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *cdb, uint8_t *buffer, uint32_t *len) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - return scsi_disk_read_capacity(scsi_disk[id], cdb, buffer, len); - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom_read_capacity(cdrom[id], cdb, buffer, len); - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - return zip_read_capacity(zip[id], cdb, buffer, len); - default: - return 0; - } -} - - -int scsi_device_present(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t main_lun_type = SCSIDevices[scsi_id][0].LunType; - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - if ((main_lun_type != SCSI_NONE) && (lun_type == SCSI_NONE) && scsi_lun) - lun_type = SCSI_NULL; - - switch (lun_type) - { - case SCSI_NONE: - return 0; - default: - return 1; - } -} - - -int scsi_device_valid(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - break; - default: - id = 0; - break; - } - - return (id == 0xFF) ? 0 : 1; -} - - -int scsi_device_cdb_length(uint8_t scsi_id, uint8_t scsi_lun) -{ - /* Right now, it's 12 for all devices. */ - return 12; -} - - -void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8_t *cdb) -{ - uint8_t id = 0; - uint8_t main_lun_type = SCSIDevices[scsi_id][0].LunType; - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - if ((main_lun_type != SCSI_NONE) && (lun_type == SCSI_NONE) && scsi_lun) - lun_type = SCSI_NULL; - - switch (lun_type) { - case SCSI_NULL: - id = 0; - scsi_null_set_location(scsi_id, scsi_lun); - break; - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - break; - default: - id = 0; - SCSIDevices[scsi_id][scsi_lun].Phase = SCSI_PHASE_STATUS; - SCSIDevices[scsi_id][scsi_lun].Status = SCSI_STATUS_CHECK_CONDITION; - return; - } - - /* - * Since that field in the target struct is never used when - * the bus type is SCSI, let's use it for this scope. - */ - scsi_device_target_save_cdb_byte(lun_type, id, cdb[1]); - - if (cdb_len != 12) { - /* - * Make sure the LUN field of the temporary CDB is always 0, - * otherwise Daemon Tools drives will misbehave when a command - * is passed through to them. - */ - cdb[1] &= 0x1f; - } - - /* Finally, execute the SCSI command immediately and get the transfer length. */ - SCSIDevices[scsi_id][scsi_lun].Phase = SCSI_PHASE_COMMAND; - SCSIDevices[scsi_id][scsi_lun].Status = scsi_device_target_command(lun_type, id, cdb); - - if (SCSIDevices[scsi_id][scsi_lun].Phase == SCSI_PHASE_STATUS) { - /* Command completed (either OK or error) - call the phase callback to complete the command. */ - scsi_device_target_phase_callback(lun_type, id); - } - /* If the phase is DATA IN or DATA OUT, finish this here. */ -} - -void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t id = 0; - uint8_t main_lun_type = SCSIDevices[scsi_id][0].LunType; - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - if ((main_lun_type != SCSI_NONE) && (lun_type == SCSI_NONE) && scsi_lun) - lun_type = SCSI_NULL; - - switch (lun_type) { - case SCSI_NULL: - id = 0; - break; - case SCSI_DISK: - id = scsi_disks[scsi_id][scsi_lun]; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - break; - default: - id = 0; - return; - } - - /* Call the second phase. */ - scsi_device_target_phase_callback(lun_type, id); - SCSIDevices[scsi_id][scsi_lun].Status = scsi_device_target_err_stat_to_scsi(lun_type, id); - /* Command second phase complete - call the callback to complete the command. */ - scsi_device_target_phase_callback(lun_type, id); -} - -int32_t *scsi_device_get_buf_len(uint8_t scsi_id, uint8_t scsi_lun) -{ - return &SCSIDevices[scsi_id][scsi_lun].BufferLength; -} diff --git a/backup code/scsi/scsi_device - Cópia.c b/backup code/scsi/scsi_device - Cópia.c deleted file mode 100644 index e4eeb5a0f..000000000 --- a/backup code/scsi/scsi_device - Cópia.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * 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. - * - * The generic SCSI device command handler. - * - * Version: @(#)scsi_device.c 1.0.16 2018/03/26 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../disk/hdd.h" -#include "../disk/zip.h" -#include "scsi.h" -#include "../cdrom/cdrom.h" -#include "scsi_disk.h" - - -static uint8_t scsi_null_device_sense[14] = { 0x70,0,SENSE_ILLEGAL_REQUEST,0,0,0,0,0,0,0,0,0,ASC_INV_LUN,0 }; - - -static uint8_t scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb) -{ - if (lun_type == SCSI_DISK) - { - scsi_hd_command(id, cdb); - return scsi_hd_err_stat_to_scsi(id); - } - else if (lun_type == SCSI_CDROM) - { - cdrom_command(cdrom[id], cdb); - return cdrom_CDROM_PHASE_to_scsi(cdrom[id]); - } - else if (lun_type == SCSI_ZIP) - { - zip_command(id, cdb); - return zip_ZIP_PHASE_to_scsi(id); - } - else - { - return SCSI_STATUS_CHECK_CONDITION; - } -} - - -static void scsi_device_target_phase_callback(int lun_type, uint8_t id) -{ - if (lun_type == SCSI_DISK) - { - scsi_hd_callback(id); - } - else if (lun_type == SCSI_CDROM) - { - cdrom_phase_callback(cdrom[id]); - } - else if (lun_type == SCSI_ZIP) - { - zip_phase_callback(id); - } - else - { - return; - } -} - - -static int scsi_device_target_err_stat_to_scsi(int lun_type, uint8_t id) -{ - if (lun_type == SCSI_DISK) - { - return scsi_hd_err_stat_to_scsi(id); - } - else if (lun_type == SCSI_CDROM) - { - return cdrom_CDROM_PHASE_to_scsi(cdrom[id]); - } - else if (lun_type == SCSI_ZIP) - { - return zip_ZIP_PHASE_to_scsi(id); - } - else - { - return SCSI_STATUS_CHECK_CONDITION; - } -} - - -static void scsi_device_target_save_cdb_byte(int lun_type, uint8_t id, uint8_t cdb_byte) -{ - if (lun_type == SCSI_DISK) - { - shdc[id].request_length = cdb_byte; - } - else if (lun_type == SCSI_CDROM) - { - cdrom[id]->request_length = cdb_byte; - } - else if (lun_type == SCSI_ZIP) - { - zip[id]->request_length = cdb_byte; - } - else - { - return; - } -} - - -int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - return shdc[id].callback; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id]->callback; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - return zip[id]->callback; - break; - default: - return -1LL; - break; - } -} - - -uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - return shdc[id].sense; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id]->sense; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - return zip[id]->sense; - break; - default: - return scsi_null_device_sense; - break; - } -} - - -void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffer, uint8_t alloc_length) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - scsi_hd_request_sense_for_scsi(id, buffer, alloc_length); - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - cdrom_request_sense_for_scsi(cdrom[id], buffer, alloc_length); - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - zip_request_sense_for_scsi(id, buffer, alloc_length); - break; - default: - memcpy(buffer, scsi_null_device_sense, alloc_length); - break; - } -} - - -void scsi_device_reset(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - scsi_hd_reset(id); - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - cdrom_reset(cdrom[id]); - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - zip_reset(id); - break; - } -} - - -void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uint8_t *rmb) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - switch (lun_type) - { - case SCSI_DISK: - *type = *rmb = 0x00; - break; - case SCSI_CDROM: - *type = 0x05; - *rmb = 0x80; - break; - case SCSI_ZIP: - *type = 0x00; - *rmb = 0x80; - break; - default: - *type = *rmb = 0xff; - break; - } -} - - -int scsi_device_read_capacity(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *cdb, uint8_t *buffer, uint32_t *len) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - return scsi_hd_read_capacity(id, cdb, buffer, len); - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom_read_capacity(cdrom[id], cdb, buffer, len); - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - return zip_read_capacity(id, cdb, buffer, len); - default: - return 0; - } -} - - -int scsi_device_present(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - switch (lun_type) - { - case SCSI_NONE: - return 0; - default: - return 1; - } -} - - -int scsi_device_valid(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - break; - default: - id = 0; - break; - } - - return (id == 0xFF) ? 0 : 1; -} - - -int scsi_device_cdb_length(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id]->cdb_len; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - return zip[id]->cdb_len; - default: - return 12; - } -} - - -void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8_t *cdb) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - break; - default: - id = 0; - SCSIDevices[scsi_id][scsi_lun].Phase = SCSI_PHASE_STATUS; - SCSIDevices[scsi_id][scsi_lun].Status = SCSI_STATUS_CHECK_CONDITION; - return; - } - - /* - * Since that field in the target struct is never used when - * the bus type is SCSI, let's use it for this scope. - */ - scsi_device_target_save_cdb_byte(lun_type, id, cdb[1]); - - if (cdb_len != 12) { - /* - * Make sure the LUN field of the temporary CDB is always 0, - * otherwise Daemon Tools drives will misbehave when a command - * is passed through to them. - */ - cdb[1] &= 0x1f; - } - - /* Finally, execute the SCSI command immediately and get the transfer length. */ - SCSIDevices[scsi_id][scsi_lun].Phase = SCSI_PHASE_COMMAND; - SCSIDevices[scsi_id][scsi_lun].Status = scsi_device_target_command(lun_type, id, cdb); - - if (SCSIDevices[scsi_id][scsi_lun].Phase == SCSI_PHASE_STATUS) { - /* Command completed (either OK or error) - call the phase callback to complete the command. */ - scsi_device_target_phase_callback(lun_type, id); - } - /* If the phase is DATA IN or DATA OUT, finish this here. */ -} - -void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType; - - uint8_t id = 0; - - switch (lun_type) - { - case SCSI_DISK: - id = scsi_hard_disks[scsi_id][scsi_lun]; - break; - case SCSI_CDROM: - id = scsi_cdrom_drives[scsi_id][scsi_lun]; - break; - case SCSI_ZIP: - id = scsi_zip_drives[scsi_id][scsi_lun]; - break; - default: - id = 0; - return; - } - - /* Call the second phase. */ - scsi_device_target_phase_callback(lun_type, id); - SCSIDevices[scsi_id][scsi_lun].Status = scsi_device_target_err_stat_to_scsi(lun_type, id); - /* Command second phase complete - call the callback to complete the command. */ - scsi_device_target_phase_callback(lun_type, id); -} - -int32_t *scsi_device_get_buf_len(uint8_t scsi_id, uint8_t scsi_lun) -{ - return &SCSIDevices[scsi_id][scsi_lun].BufferLength; -} diff --git a/backup code/scsi/scsi_device - Cópia.h b/backup code/scsi/scsi_device - Cópia.h deleted file mode 100644 index 61c92f699..000000000 --- a/backup code/scsi/scsi_device - Cópia.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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. - * - * Definitions for the generic SCSI device command handler. - * - * Version: @(#)scsi_device.h 1.0.8 2018/06/12 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - */ -#ifndef SCSI_DEVICE_H -# define SCSI_DEVICE_H - -typedef struct -{ - int state; - int new_state; - int clear_req; - uint32_t bus_in, bus_out; - int dev_id; - - int command_pos; - uint8_t command[20]; - int data_pos; - - int change_state_delay; - int new_req_delay; -} scsi_bus_t; - -extern uint8_t *scsi_device_sense(uint8_t id, uint8_t lun); -extern void scsi_device_type_data(uint8_t id, uint8_t lun, - uint8_t *type, uint8_t *rmb); -extern int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun); -extern void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, - uint8_t *buffer, - uint8_t alloc_length); -extern void scsi_device_reset(uint8_t scsi_id, uint8_t scsi_lun); -extern int scsi_device_read_capacity(uint8_t id, uint8_t lun, - uint8_t *cdb, uint8_t *buffer, - uint32_t *len); -extern int scsi_device_present(uint8_t id, uint8_t lun); -extern int scsi_device_valid(uint8_t id, uint8_t lun); -extern int scsi_device_cdb_length(uint8_t id, uint8_t lun); -extern void scsi_device_command(uint8_t id, uint8_t lun, int cdb_len, - uint8_t *cdb); -extern void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, - int cdb_len, uint8_t *cdb); -extern void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun); -extern int32_t *scsi_device_get_buf_len(uint8_t scsi_id, uint8_t scsi_lun); - -extern int scsi_bus_update(scsi_bus_t *bus, int bus_assert); -extern int scsi_bus_read(scsi_bus_t *bus); -extern int scsi_bus_match(scsi_bus_t *bus, int bus_assert); - -extern int scsi_null_err_stat_to_scsi(void); -extern void scsi_null_request_sense(uint8_t *buffer, uint8_t alloc_length, int desc); -extern void scsi_null_request_sense_for_scsi(uint8_t *buffer, uint8_t alloc_length); -extern void scsi_null_command(uint8_t *cdb); -extern void scsi_null_callback(void); -extern void scsi_null_set_location(uint8_t id, uint8_t lun); - -extern uint8_t scsi_null_device_sense[18]; - -#endif /*SCSI_DEVICE_H*/ diff --git a/backup code/scsi/scsi_disk - Cópia.c b/backup code/scsi/scsi_disk - Cópia.c deleted file mode 100644 index d72413a13..000000000 --- a/backup code/scsi/scsi_disk - Cópia.c +++ /dev/null @@ -1,1291 +0,0 @@ -/* - * 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. - * - * Emulation of SCSI fixed disks. - * - * Version: @(#)scsi_disk.c 1.0.20 2018/05/28 - * - * Author: Miran Grca, - * - * Copyright 2017,2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../device.h" -#include "../nvr.h" -#include "../piix.h" -#include "../disk/hdd.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../plat.h" -#include "../ui.h" -#include "scsi.h" -#include "../cdrom/cdrom.h" -#include "scsi_disk.h" - - -/* Bits of 'status' */ -#define ERR_STAT 0x01 -#define DRQ_STAT 0x08 /* Data request */ -#define DSC_STAT 0x10 -#define SERVICE_STAT 0x10 -#define READY_STAT 0x40 -#define BUSY_STAT 0x80 - -/* Bits of 'error' */ -#define ABRT_ERR 0x04 /* Command aborted */ -#define MCR_ERR 0x08 /* Media change request */ - -#define MAX_BLOCKS_AT_ONCE 340 - -#define scsi_hd_sense_error shdc[id].sense[0] -#define scsi_hd_sense_key shdc[id].sense[2] -#define scsi_hd_asc shdc[id].sense[12] -#define scsi_hd_ascq shdc[id].sense[13] - - -scsi_hard_disk_t shdc[HDD_NUM]; -FILE *shdf[HDD_NUM]; - -uint8_t scsi_hard_disks[16][8] = { - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } -}; - - -/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ -const uint8_t scsi_hd_command_flags[0x100] = { - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ - 0, - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ - 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x08 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ - 0, 0, 0, 0, 0, 0, - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ - 0, - IMPLEMENTED, /* 0x15 */ - IMPLEMENTED | SCSI_ONLY, /* 0x16 */ - IMPLEMENTED | SCSI_ONLY, /* 0x17 */ - 0, 0, - IMPLEMENTED, /* 0x1A */ - 0, 0, - IMPLEMENTED, /* 0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x25 */ - 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x28 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ - 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, - IMPLEMENTED | CHECK_READY, /* 0x41 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0x55 */ - 0, 0, 0, 0, - IMPLEMENTED, /* 0x5A */ - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xA8 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0xAA */ - 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0xBD */ - 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - - -uint64_t scsi_hd_mode_sense_page_flags = (1LL << 0x03) | (1LL << 0x04) | (1LL << 0x30) | (1LL << 0x3F); - -/* This should be done in a better way but for time being, it's been done this way so it's not as huge and more readable. */ -static const mode_sense_pages_t scsi_hd_mode_sense_pages_default = -{ { [0x03] = { 0x03, 0x16, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - [0x04] = { 0x04, 0x16, 0, 0x10, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0 }, - [0x30] = { 0xB0, 0x16, '8', '6', 'B', 'o', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } -} }; - -static const mode_sense_pages_t scsi_hd_mode_sense_pages_changeable = -{ { [0x03] = { 0x03, 0x16, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - [0x04] = { 0x04, 0x16, 0, 0x10, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0 }, - [0x30] = { 0xB0, 0x16, '8', '6', 'B', 'o', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } -} }; - -static mode_sense_pages_t scsi_hd_mode_sense_pages_saved[HDD_NUM]; - - -#ifdef ENABLE_SCSI_DISK_LOG -int scsi_hd_do_log = ENABLE_SCSI_DISK_LOG; -#endif - - -static void -scsi_hd_log(const char *fmt, ...) -{ -#ifdef ENABLE_SCSI_DISK_LOG - va_list ap; - - if (scsi_hd_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -/* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ -int -scsi_hd_err_stat_to_scsi(uint8_t id) -{ - if (shdc[id].status & ERR_STAT) - return SCSI_STATUS_CHECK_CONDITION; - else - return SCSI_STATUS_OK; -} - - -int -find_hdd_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t i = 0; - - for (i = 0; i < HDD_NUM; i++) { - if (wcslen(hdd[i].fn) == 0) - continue; - if ((hdd[i].spt == 0) || (hdd[i].hpc == 0) || (hdd[i].tracks == 0)) - continue; - if ((hdd[i].bus == HDD_BUS_SCSI) && (hdd[i].scsi_id == scsi_id) && (hdd[i].scsi_lun == scsi_lun)) - return i; - } - return 0xff; -} - - -void -scsi_loadhd(int scsi_id, int scsi_lun, int id) -{ - if (! hdd_image_load(id)) - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; -} - - -void -build_scsi_hd_map(void) -{ - uint8_t i = 0, j = 0; - - for (i = 0; i < 16; i++) - memset(scsi_hard_disks[i], 0xff, 8); - - for (i = 0; i < 16; i++) { - for (j = 0; j < 8; j++) { - scsi_hard_disks[i][j] = find_hdd_for_scsi_id(i, j); - if (scsi_hard_disks[i][j] != 0xff) { - memset(&(shdc[scsi_hard_disks[i][j]]), 0, - sizeof(shdc[scsi_hard_disks[i][j]])); - if (wcslen(hdd[scsi_hard_disks[i][j]].fn) > 0) - scsi_loadhd(i, j, scsi_hard_disks[i][j]); - } - } - } -} - - -void -scsi_hd_mode_sense_load(uint8_t id) -{ - FILE *f; - wchar_t file_name[512]; - int i; - memset(&scsi_hd_mode_sense_pages_saved[id], 0, sizeof(mode_sense_pages_t)); - for (i = 0; i < 0x3f; i++) { - if (scsi_hd_mode_sense_pages_default.pages[i][1] != 0) - memcpy(scsi_hd_mode_sense_pages_saved[id].pages[i], scsi_hd_mode_sense_pages_default.pages[i], scsi_hd_mode_sense_pages_default.pages[i][1] + 2); - } - swprintf(file_name, 512, L"scsi_hd_%02i_mode_sense.bin", id); - memset(file_name, 0, 512 * sizeof(wchar_t)); - f = plat_fopen(nvr_path(file_name), L"rb"); - if (f) { - fread(scsi_hd_mode_sense_pages_saved[id].pages[0x30], 1, 0x18, f); - fclose(f); - } -} - - -void -scsi_hd_mode_sense_save(uint8_t id) -{ - FILE *f; - wchar_t file_name[512]; - memset(file_name, 0, 512 * sizeof(wchar_t)); - swprintf(file_name, 512, L"scsi_hd_%02i_mode_sense.bin", id); - f = plat_fopen(nvr_path(file_name), L"wb"); - if (f) { - fwrite(scsi_hd_mode_sense_pages_saved[id].pages[0x30], 1, 0x18, f); - fclose(f); - } -} - - -int -scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len) -{ - int size = 0; - - size = hdd_image_get_last_sector(id); - memset(buffer, 0, 8); - buffer[0] = (size >> 24) & 0xff; - buffer[1] = (size >> 16) & 0xff; - buffer[2] = (size >> 8) & 0xff; - buffer[3] = size & 0xff; - buffer[6] = 2; /* 512 = 0x0200 */ - *len = 8; - - return 1; -} - - -/*SCSI Mode Sense 6/10*/ -uint8_t -scsi_hd_mode_sense_read(uint8_t id, uint8_t page_control, uint8_t page, uint8_t pos) -{ - switch (page_control) { - case 0: - case 3: - return scsi_hd_mode_sense_pages_saved[id].pages[page][pos]; - break; - case 1: - return scsi_hd_mode_sense_pages_changeable.pages[page][pos]; - break; - case 2: - return scsi_hd_mode_sense_pages_default.pages[page][pos]; - break; - } - - return 0; -} - - -uint32_t -scsi_hd_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len) -{ - uint8_t msplen, page_control = (type >> 6) & 3; - - int i = 0, j = 0; - int size = 0; - - type &= 0x3f; - - size = hdd_image_get_last_sector(id); - - if (block_descriptor_len) { - buf[pos++] = 1; /* Density code. */ - buf[pos++] = (size >> 16) & 0xff; /* Number of blocks (0 = all). */ - buf[pos++] = (size >> 8) & 0xff; - buf[pos++] = size & 0xff; - buf[pos++] = 0; /* Reserved. */ - buf[pos++] = 0; /* Block length (0x200 = 512 bytes). */ - buf[pos++] = 2; - buf[pos++] = 0; - } - - for (i = 0; i < 0x40; i++) { - if ((type == GPMODE_ALL_PAGES) || (type == i)) { - if (scsi_hd_mode_sense_page_flags & (1LL << shdc[id].current_page_code)) { - buf[pos++] = scsi_hd_mode_sense_read(id, page_control, i, 0); - msplen = scsi_hd_mode_sense_read(id, page_control, i, 1); - buf[pos++] = msplen; - scsi_hd_log("SCSI HDD %i: MODE SENSE: Page [%02X] length %i\n", id, i, msplen); - for (j = 0; j < msplen; j++) - buf[pos++] = scsi_hd_mode_sense_read(id, page_control, i, 2 + j); - } - } - } - - return pos; -} - - -static void -scsi_hd_command_common(uint8_t id) -{ - shdc[id].status = BUSY_STAT; - shdc[id].phase = 1; - if (shdc[id].packet_status == CDROM_PHASE_COMPLETE) { - scsi_hd_callback(id); - shdc[id].callback = 0LL; - } else - shdc[id].callback = -1LL; /* Speed depends on SCSI controller */ -} - - -static void -scsi_hd_command_complete(uint8_t id) -{ - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - scsi_hd_command_common(id); -} - - -static void -scsi_hd_command_read_dma(uint8_t id) -{ - shdc[id].packet_status = CDROM_PHASE_DATA_IN_DMA; - scsi_hd_command_common(id); -} - - -static void -scsi_hd_command_write_dma(uint8_t id) -{ - shdc[id].packet_status = CDROM_PHASE_DATA_OUT_DMA; - scsi_hd_command_common(id); -} - - -static void -scsi_hd_data_command_finish(uint8_t id, int len, int block_len, int alloc_len, int direction) -{ - scsi_hd_log("SCSI HD %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", id, - shdc[id].current_cdb[0], len, block_len, alloc_len, direction, shdc[id].request_length); - if (alloc_len >= 0) { - if (alloc_len < len) - len = alloc_len; - } - if (len == 0) - scsi_hd_command_complete(id); - else { - if (direction == 0) - scsi_hd_command_read_dma(id); - else - scsi_hd_command_write_dma(id); - } -} - - -static void -scsi_hd_sense_clear(int id, int command) -{ - scsi_hd_sense_key = scsi_hd_asc = scsi_hd_ascq = 0; -} - - -static void -scsi_hd_set_phase(uint8_t id, uint8_t phase) -{ - uint8_t scsi_id = hdd[id].scsi_id; - uint8_t scsi_lun = hdd[id].scsi_lun; - - if (hdd[id].bus != HDD_BUS_SCSI) - return; - - SCSIDevices[scsi_id][scsi_lun].Phase = phase; -} - - -static void -scsi_hd_cmd_error(uint8_t id) -{ - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - shdc[id].error = ((scsi_hd_sense_key & 0xf) << 4) | ABRT_ERR; - shdc[id].status = READY_STAT | ERR_STAT; - shdc[id].phase = 3; - shdc[id].packet_status = 0x80; - shdc[id].callback = 50 * SCSI_TIME; - scsi_hd_log("SCSI HD %i: ERROR: %02X/%02X/%02X\n", id, scsi_hd_sense_key, scsi_hd_asc, scsi_hd_ascq); -} - - -static void -scsi_hd_invalid_lun(uint8_t id) -{ - scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_hd_asc = ASC_INV_LUN; - scsi_hd_ascq = 0; - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_cmd_error(id); -} - - -static void -scsi_hd_illegal_opcode(uint8_t id) -{ - scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_hd_asc = ASC_ILLEGAL_OPCODE; - scsi_hd_ascq = 0; - scsi_hd_cmd_error(id); -} - - -static void -scsi_hd_lba_out_of_range(uint8_t id) -{ - scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_hd_asc = ASC_LBA_OUT_OF_RANGE; - scsi_hd_ascq = 0; - scsi_hd_cmd_error(id); -} - - -static void -scsi_hd_invalid_field(uint8_t id) -{ - scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_hd_asc = ASC_INV_FIELD_IN_CMD_PACKET; - scsi_hd_ascq = 0; - scsi_hd_cmd_error(id); - shdc[id].status = 0x53; -} - - -static void -scsi_hd_invalid_field_pl(uint8_t id) -{ - scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_hd_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; - scsi_hd_ascq = 0; - scsi_hd_cmd_error(id); - shdc[id].status = 0x53; -} - - -static void -scsi_hd_data_phase_error(uint8_t id) -{ - scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_hd_asc = ASC_DATA_PHASE_ERROR; - scsi_hd_ascq = 0; - scsi_hd_cmd_error(id); -} - - -static int -scsi_hd_pre_execution_check(uint8_t id, uint8_t *cdb) -{ - if (((shdc[id].request_length >> 5) & 7) != hdd[id].scsi_lun) { - scsi_hd_log("SCSI HD %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", - id, ((shdc[id].request_length >> 5) & 7)); - scsi_hd_invalid_lun(id); - return 0; - } - - if (!(scsi_hd_command_flags[cdb[0]] & IMPLEMENTED)) { - scsi_hd_log("SCSI HD %i: Attempting to execute unknown command %02X\n", id, cdb[0]); - scsi_hd_illegal_opcode(id); - return 0; - } - - /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* - the UNIT ATTENTION condition if it's set. */ - if (cdb[0] != GPCMD_REQUEST_SENSE) - scsi_hd_sense_clear(id, cdb[0]); - - scsi_hd_log("SCSI HD %i: Continuing with command\n", id); - - return 1; -} - - -static void -scsi_hd_seek(uint8_t id, uint32_t pos) -{ - /* scsi_hd_log("SCSI HD %i: Seek %08X\n", id, pos); */ - hdd_image_seek(id, pos); -} - - -static void -scsi_hd_rezero(uint8_t id) -{ - if (id == 0xff) - return; - - shdc[id].sector_pos = shdc[id].sector_len = 0; - scsi_hd_seek(id, 0); -} - - -void -scsi_hd_reset(uint8_t id) -{ - scsi_hd_rezero(id); - shdc[id].status = 0; - shdc[id].callback = 0; - shdc[id].packet_status = 0xff; -} - - -void -scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length, int desc) -{ - /*Will return 18 bytes of 0*/ - if (alloc_length != 0) { - memset(buffer, 0, alloc_length); - if (!desc) - memcpy(buffer, shdc[id].sense, alloc_length); - else { - buffer[1] = scsi_hd_sense_key; - buffer[2] = scsi_hd_asc; - buffer[3] = scsi_hd_ascq; - } - } else - return; - - buffer[0] = 0x70; - - scsi_hd_log("SCSI HD %i: Reporting sense: %02X %02X %02X\n", id, buffer[2], buffer[12], buffer[13]); - - /* Clear the sense stuff as per the spec. */ - scsi_hd_sense_clear(id, GPCMD_REQUEST_SENSE); -} - - -void -scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length) -{ - scsi_hd_request_sense(id, buffer, alloc_length, 0); -} - - -void -scsi_hd_command(uint8_t id, uint8_t *cdb) -{ - uint8_t *hdbufferb = SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].CmdBuffer; - uint32_t len; - int max_len, pos = 0; - unsigned idx = 0; - unsigned size_idx, preamble_len; - uint32_t alloc_length, last_sector = 0; - char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; - char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; - int block_desc = 0; - int32_t *BufLen = &SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].BufferLength; - - last_sector = hdd_image_get_last_sector(id); - - shdc[id].status &= ~ERR_STAT; - shdc[id].packet_len = 0; - - device_identify[6] = (id / 10) + 0x30; - device_identify[7] = (id % 10) + 0x30; - - device_identify_ex[6] = (id / 10) + 0x30; - device_identify_ex[7] = (id % 10) + 0x30; - device_identify_ex[10] = EMU_VERSION[0]; - device_identify_ex[12] = EMU_VERSION[2]; - device_identify_ex[13] = EMU_VERSION[3]; - - memcpy(shdc[id].current_cdb, cdb, 12); - - if (cdb[0] != 0) { - scsi_hd_log("SCSI HD %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X\n", - id, cdb[0], scsi_hd_sense_key, scsi_hd_asc, scsi_hd_ascq); - scsi_hd_log("SCSI HD %i: Request length: %04X\n", id, shdc[id].request_length); - - scsi_hd_log("SCSI HD %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", id, - cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], - cdb[8], cdb[9], cdb[10], cdb[11]); - } - - shdc[id].sector_len = 0; - - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - - /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ - if (scsi_hd_pre_execution_check(id, cdb) == 0) - return; - - switch (cdb[0]) { - case GPCMD_SEND_DIAGNOSTIC: - if (!(cdb[1] & (1 << 2))) { - scsi_hd_invalid_field(id); - return; - } - case GPCMD_SCSI_RESERVE: - case GPCMD_SCSI_RELEASE: - case GPCMD_TEST_UNIT_READY: - case GPCMD_FORMAT_UNIT: - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_command_complete(id); - break; - - case GPCMD_REZERO_UNIT: - shdc[id].sector_pos = shdc[id].sector_len = 0; - scsi_hd_seek(id, 0); - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - break; - - case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ - if ((*BufLen == -1) || (cdb[4] < *BufLen)) - *BufLen = cdb[4]; - - if (*BufLen < cdb[4]) - cdb[4] = *BufLen; - - len = (cdb[1] & 1) ? 8 : 18; - - scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); - scsi_hd_data_command_finish(id, len, len, cdb[4], 0); - break; - - case GPCMD_MECHANISM_STATUS: - len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - - if ((*BufLen == -1) || (len < *BufLen)) - *BufLen = len; - - scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); - scsi_hd_data_command_finish(id, 8, 8, len, 0); - break; - - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - switch(cdb[0]) { - case GPCMD_READ_6: - shdc[id].sector_len = cdb[4]; - shdc[id].sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - break; - case GPCMD_READ_10: - shdc[id].sector_len = (cdb[7] << 8) | cdb[8]; - shdc[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - break; - case GPCMD_READ_12: - shdc[id].sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - shdc[id].sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } - - if ((shdc[id].sector_pos > last_sector) || - ((shdc[id].sector_pos + shdc[id].sector_len - 1) > last_sector)) { - scsi_hd_lba_out_of_range(id); - return; - } - - if ((!shdc[id].sector_len) || (*BufLen == 0)) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_log("SCSI HD %i: All done - callback set\n", id); - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - shdc[id].callback = 20 * SCSI_TIME; - break; - } - - max_len = shdc[id].sector_len; - shdc[id].requested_blocks = max_len; - - alloc_length = shdc[id].packet_len = max_len << 9; - - if ((*BufLen == -1) || (alloc_length < *BufLen)) - *BufLen = alloc_length; - - scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); - - if (shdc[id].requested_blocks > 1) - scsi_hd_data_command_finish(id, alloc_length, alloc_length / shdc[id].requested_blocks, alloc_length, 0); - else - scsi_hd_data_command_finish(id, alloc_length, alloc_length, alloc_length, 0); - return; - - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - if (!(cdb[1] & 2)) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_command_complete(id); - break; - } - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - switch(cdb[0]) - { - case GPCMD_VERIFY_6: - case GPCMD_WRITE_6: - shdc[id].sector_len = cdb[4]; - shdc[id].sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - scsi_hd_log("SCSI HD %i: Length: %i, LBA: %i\n", id, shdc[id].sector_len, shdc[id].sector_pos); - break; - case GPCMD_VERIFY_10: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - shdc[id].sector_len = (cdb[7] << 8) | cdb[8]; - shdc[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - scsi_hd_log("SCSI HD %i: Length: %i, LBA: %i\n", id, shdc[id].sector_len, shdc[id].sector_pos); - break; - case GPCMD_VERIFY_12: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - shdc[id].sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - shdc[id].sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - break; - } - - if ((shdc[id].sector_pos > last_sector) || - ((shdc[id].sector_pos + shdc[id].sector_len - 1) > last_sector)) { - scsi_hd_lba_out_of_range(id); - return; - } - - if ((!shdc[id].sector_len) || (*BufLen == 0)) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_log("SCSI HD %i: All done - callback set\n", id); - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - shdc[id].callback = 20 * SCSI_TIME; - break; - } - - max_len = shdc[id].sector_len; - shdc[id].requested_blocks = max_len; - - alloc_length = shdc[id].packet_len = max_len << 9; - - if ((*BufLen == -1) || (alloc_length < *BufLen)) - *BufLen = alloc_length; - - scsi_hd_set_phase(id, SCSI_PHASE_DATA_OUT); - - if (shdc[id].requested_blocks > 1) - scsi_hd_data_command_finish(id, alloc_length, alloc_length / shdc[id].requested_blocks, alloc_length, 1); - else - scsi_hd_data_command_finish(id, alloc_length, alloc_length, alloc_length, 1); - return; - - case GPCMD_WRITE_SAME_10: - if ((cdb[1] & 6) == 6) { - scsi_hd_invalid_field(id); - return; - } - - shdc[id].sector_len = (cdb[7] << 8) | cdb[8]; - shdc[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - scsi_hd_log("SCSI HD %i: Length: %i, LBA: %i\n", id, shdc[id].sector_len, shdc[id].sector_pos); - - if ((shdc[id].sector_pos > last_sector) || - ((shdc[id].sector_pos + shdc[id].sector_len - 1) > last_sector)) { - scsi_hd_lba_out_of_range(id); - return; - } - - if ((!shdc[id].sector_len) || (*BufLen == 0)) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_log("SCSI HD %i: All done - callback set\n", id); - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - shdc[id].callback = 20 * SCSI_TIME; - break; - } - - max_len = 1; - shdc[id].requested_blocks = max_len; - - alloc_length = shdc[id].packet_len = max_len << 9; - - if ((*BufLen == -1) || (alloc_length < *BufLen)) - *BufLen = alloc_length; - - scsi_hd_set_phase(id, SCSI_PHASE_DATA_OUT); - - if (shdc[id].requested_blocks > 1) - scsi_hd_data_command_finish(id, alloc_length, alloc_length / shdc[id].requested_blocks, alloc_length, 1); - else - scsi_hd_data_command_finish(id, alloc_length, alloc_length, alloc_length, 1); - return; - - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); - - block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; - - if (cdb[0] == GPCMD_MODE_SENSE_6) - len = cdb[4]; - else - len = (cdb[8] | (cdb[7] << 8)); - - shdc[id].current_page_code = cdb[2] & 0x3F; - - alloc_length = len; - - shdc[id].temp_buffer = (uint8_t *) malloc(65536); - memset(shdc[id].temp_buffer, 0, 65536); - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = scsi_hd_mode_sense(id, shdc[id].temp_buffer, 4, cdb[2], block_desc); - if (len > alloc_length) - len = alloc_length; - shdc[id].temp_buffer[0] = len - 1; - shdc[id].temp_buffer[1] = 0; - if (block_desc) - shdc[id].temp_buffer[3] = 8; - } else { - len = scsi_hd_mode_sense(id, shdc[id].temp_buffer, 8, cdb[2], block_desc); - if (len > alloc_length) - len = alloc_length; - shdc[id].temp_buffer[0]=(len - 2) >> 8; - shdc[id].temp_buffer[1]=(len - 2) & 255; - shdc[id].temp_buffer[2] = 0; - if (block_desc) { - shdc[id].temp_buffer[6] = 0; - shdc[id].temp_buffer[7] = 8; - } - } - - if (len > alloc_length) - len = alloc_length; - else if (len < alloc_length) - alloc_length = len; - - if ((*BufLen == -1) || (alloc_length < *BufLen)) - *BufLen = alloc_length; - - scsi_hd_log("SCSI HDD %i: Reading mode page: %02X...\n", id, cdb[2]); - - scsi_hd_data_command_finish(id, len, len, alloc_length, 0); - return; - - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - scsi_hd_set_phase(id, SCSI_PHASE_DATA_OUT); - - if (cdb[0] == GPCMD_MODE_SELECT_6) - len = cdb[4]; - else - len = (cdb[7] << 8) | cdb[8]; - - if ((*BufLen == -1) || (len < *BufLen)) - *BufLen = len; - - shdc[id].total_length = len; - shdc[id].do_page_save = cdb[1] & 1; - - scsi_hd_data_command_finish(id, len, len, len, 1); - return; - - case GPCMD_INQUIRY: - max_len = cdb[3]; - max_len <<= 8; - max_len |= cdb[4]; - - if ((!max_len) || (*BufLen == 0)) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - shdc[id].callback = 20 * SCSI_TIME; - break; - } - - shdc[id].temp_buffer = malloc(1024); - - if (cdb[1] & 1) { - preamble_len = 4; - size_idx = 3; - - shdc[id].temp_buffer[idx++] = 05; - shdc[id].temp_buffer[idx++] = cdb[2]; - shdc[id].temp_buffer[idx++] = 0; - - idx++; - - switch (cdb[2]) { - case 0x00: - shdc[id].temp_buffer[idx++] = 0x00; - shdc[id].temp_buffer[idx++] = 0x83; - break; - case 0x83: - if (idx + 24 > max_len) { - free(shdc[id].temp_buffer); - shdc[id].temp_buffer = NULL; - scsi_hd_data_phase_error(id); - return; - } - - shdc[id].temp_buffer[idx++] = 0x02; - shdc[id].temp_buffer[idx++] = 0x00; - shdc[id].temp_buffer[idx++] = 0x00; - shdc[id].temp_buffer[idx++] = 20; - ide_padstr8(shdc[id].temp_buffer + idx, 20, "53R141"); /* Serial */ - idx += 20; - - if (idx + 72 > cdb[4]) - goto atapi_out; - shdc[id].temp_buffer[idx++] = 0x02; - shdc[id].temp_buffer[idx++] = 0x01; - shdc[id].temp_buffer[idx++] = 0x00; - shdc[id].temp_buffer[idx++] = 68; - ide_padstr8(shdc[id].temp_buffer + idx, 8, EMU_NAME); /* Vendor */ - idx += 8; - ide_padstr8(shdc[id].temp_buffer + idx, 40, device_identify_ex); /* Product */ - idx += 40; - ide_padstr8(shdc[id].temp_buffer + idx, 20, "53R141"); /* Product */ - idx += 20; - break; - default: - scsi_hd_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - free(shdc[id].temp_buffer); - shdc[id].temp_buffer = NULL; - scsi_hd_invalid_field(id); - return; - } - } else { - preamble_len = 5; - size_idx = 4; - - memset(shdc[id].temp_buffer, 0, 8); - shdc[id].temp_buffer[0] = 0; /*SCSI HD*/ - shdc[id].temp_buffer[1] = 0; /*Fixed*/ - shdc[id].temp_buffer[2] = 0x02; /*SCSI-2 compliant*/ - shdc[id].temp_buffer[3] = 0x02; - shdc[id].temp_buffer[4] = 31; - shdc[id].temp_buffer[6] = 1; /* 16-bit transfers supported */ - shdc[id].temp_buffer[7] = 0x20; /* Wide bus supported */ - - ide_padstr8(shdc[id].temp_buffer + 8, 8, EMU_NAME); /* Vendor */ - ide_padstr8(shdc[id].temp_buffer + 16, 16, device_identify); /* Product */ - ide_padstr8(shdc[id].temp_buffer + 32, 4, EMU_VERSION); /* Revision */ - idx = 36; - - if (max_len == 96) { - shdc[id].temp_buffer[4] = 91; - idx = 96; - } - } - -atapi_out: - shdc[id].temp_buffer[size_idx] = idx - preamble_len; - len=idx; - - scsi_hd_log("scsi_hd_command(): Inquiry (%08X, %08X)\n", hdbufferb, shdc[id].temp_buffer); - - if (len > max_len) - len = max_len; - - if ((*BufLen == -1) || (len < *BufLen)) - *BufLen = len; - - if (len > *BufLen) - len = *BufLen; - - scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); - scsi_hd_data_command_finish(id, len, len, max_len, 0); - break; - - case GPCMD_PREVENT_REMOVAL: - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_command_complete(id); - break; - - case GPCMD_SEEK_6: - case GPCMD_SEEK_10: - switch(cdb[0]) { - case GPCMD_SEEK_6: - pos = (cdb[2] << 8) | cdb[3]; - break; - case GPCMD_SEEK_10: - pos = (cdb[2] << 24) | (cdb[3]<<16) | (cdb[4]<<8) | cdb[5]; - break; - } - scsi_hd_seek(id, pos); - - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - scsi_hd_command_complete(id); - break; - - case GPCMD_READ_CDROM_CAPACITY: - shdc[id].temp_buffer = (uint8_t *) malloc(8); - - if (scsi_hd_read_capacity(id, shdc[id].current_cdb, shdc[id].temp_buffer, &len) == 0) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - return; - } - - if ((*BufLen == -1) || (len < *BufLen)) - *BufLen = len; - - scsi_hd_set_phase(id, SCSI_PHASE_DATA_IN); - scsi_hd_data_command_finish(id, len, len, len, 0); - break; - - default: - scsi_hd_illegal_opcode(id); - break; - } - - /* scsi_hd_log("SCSI HD %i: Phase: %02X, request length: %i\n", shdc[id].phase, shdc[id].request_length); */ -} - - -static void -scsi_hd_phase_data_in(uint8_t id) -{ - uint8_t *hdbufferb = SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].CmdBuffer; - int32_t *BufLen = &SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].BufferLength; - - if (!*BufLen) { - scsi_hd_log("scsi_hd_phase_data_in(): Buffer length is 0\n"); - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - - return; - } - - switch (shdc[id].current_cdb[0]) { - case GPCMD_REQUEST_SENSE: - scsi_hd_log("SCSI HDD %i: %08X, %08X\n", id, hdbufferb, *BufLen); - scsi_hd_request_sense(id, hdbufferb, *BufLen, shdc[id].current_cdb[1] & 1); - break; - case GPCMD_MECHANISM_STATUS: - memset(hdbufferb, 0, *BufLen); - hdbufferb[5] = 1; - break; - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - if ((shdc[id].requested_blocks > 0) && (*BufLen > 0)) { - if (shdc[id].packet_len > *BufLen) - hdd_image_read(id, shdc[id].sector_pos, *BufLen >> 9, hdbufferb); - else - hdd_image_read(id, shdc[id].sector_pos, shdc[id].requested_blocks, hdbufferb); - } - break; - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - case GPCMD_INQUIRY: - case GPCMD_READ_CDROM_CAPACITY: - scsi_hd_log("scsi_hd_phase_data_in(): Filling buffer (%08X, %08X)\n", hdbufferb, shdc[id].temp_buffer); - memcpy(hdbufferb, shdc[id].temp_buffer, *BufLen); - free(shdc[id].temp_buffer); - shdc[id].temp_buffer = NULL; - scsi_hd_log("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", - hdbufferb[0], hdbufferb[1], hdbufferb[2], hdbufferb[3], hdbufferb[4], hdbufferb[5], hdbufferb[6], hdbufferb[7], - hdbufferb[8], hdbufferb[9], hdbufferb[10], hdbufferb[11], hdbufferb[12], hdbufferb[13], hdbufferb[14], hdbufferb[15]); - break; - default: - fatal("SCSI HDD %i: Bad Command for phase 2 (%02X)\n", shdc[id].current_cdb[0]); - break; - } - - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); -} - - -static void -scsi_hd_phase_data_out(uint8_t id) -{ - uint8_t *hdbufferb = SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].CmdBuffer; - int i; - int32_t *BufLen = &SCSIDevices[hdd[id].scsi_id][hdd[id].scsi_lun].BufferLength; - uint32_t last_sector = hdd_image_get_last_sector(id); - uint32_t c, h, s, last_to_write = 0; - uint16_t block_desc_len, pos; - uint8_t hdr_len, val, old_val, ch, error = 0; - uint8_t page, page_len; - - if (!*BufLen) { - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); - - return; - } - - switch (shdc[id].current_cdb[0]) { - case GPCMD_VERIFY_6: - case GPCMD_VERIFY_10: - case GPCMD_VERIFY_12: - break; - case GPCMD_WRITE_6: - case GPCMD_WRITE_10: - case GPCMD_WRITE_AND_VERIFY_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_12: - if ((shdc[id].requested_blocks > 0) && (*BufLen > 0)) { - if (shdc[id].packet_len > *BufLen) - hdd_image_write(id, shdc[id].sector_pos, *BufLen >> 9, hdbufferb); - else - hdd_image_write(id, shdc[id].sector_pos, shdc[id].requested_blocks, hdbufferb); - } - break; - case GPCMD_WRITE_SAME_10: - if (!shdc[id].current_cdb[7] && !shdc[id].current_cdb[8]) - last_to_write = last_sector; - else - last_to_write = shdc[id].sector_pos + shdc[id].sector_len - 1; - - for (i = shdc[id].sector_pos; i <= last_to_write; i++) { - if (shdc[id].current_cdb[1] & 2) { - hdbufferb[0] = (i >> 24) & 0xff; - hdbufferb[1] = (i >> 16) & 0xff; - hdbufferb[2] = (i >> 8) & 0xff; - hdbufferb[3] = i & 0xff; - } else if (shdc[id].current_cdb[1] & 4) { - s = (i % hdd[id].spt); - h = ((i - s) / hdd[id].spt) % hdd[id].hpc; - c = ((i - s) / hdd[id].spt) / hdd[id].hpc; - hdbufferb[0] = (c >> 16) & 0xff; - hdbufferb[1] = (c >> 8) & 0xff; - hdbufferb[2] = c & 0xff; - hdbufferb[3] = h & 0xff; - hdbufferb[4] = (s >> 24) & 0xff; - hdbufferb[5] = (s >> 16) & 0xff; - hdbufferb[6] = (s >> 8) & 0xff; - hdbufferb[7] = s & 0xff; - } - hdd_image_write(id, i, 1, hdbufferb); - } - break; - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - if (shdc[id].current_cdb[0] == GPCMD_MODE_SELECT_10) - hdr_len = 8; - else - hdr_len = 4; - - if (shdc[id].current_cdb[0] == GPCMD_MODE_SELECT_6) { - block_desc_len = hdbufferb[2]; - block_desc_len <<= 8; - block_desc_len |= hdbufferb[3]; - } else { - block_desc_len = hdbufferb[6]; - block_desc_len <<= 8; - block_desc_len |= hdbufferb[7]; - } - - pos = hdr_len + block_desc_len; - - while(1) { - page = hdbufferb[pos] & 0x3F; - page_len = hdbufferb[pos + 1]; - - pos += 2; - - if (!(scsi_hd_mode_sense_page_flags & (1LL << ((uint64_t) page)))) - error |= 1; - else { - for (i = 0; i < page_len; i++) { - ch = scsi_hd_mode_sense_pages_changeable.pages[page][i + 2]; - val = hdbufferb[pos + i]; - old_val = scsi_hd_mode_sense_pages_saved[id].pages[page][i + 2]; - if (val != old_val) { - if (ch) - scsi_hd_mode_sense_pages_saved[id].pages[page][i + 2] = val; - else - error |= 1; - } - } - } - - pos += page_len; - - val = scsi_hd_mode_sense_pages_default.pages[page][0] & 0x80; - if (shdc[id].do_page_save && val) - scsi_hd_mode_sense_save(id); - - if (pos >= shdc[id].total_length) - break; - } - - if (error) - scsi_hd_invalid_field_pl(id); - break; - default: - fatal("SCSI HDD %i: Bad Command for phase 2 (%02X)\n", shdc[id].current_cdb[0]); - break; - } - - scsi_hd_set_phase(id, SCSI_PHASE_STATUS); -} - - -/* If the result is 1, issue an IRQ, otherwise not. */ -void -scsi_hd_callback(uint8_t id) -{ - switch(shdc[id].packet_status) { - case CDROM_PHASE_IDLE: - scsi_hd_log("SCSI HD %i: PHASE_IDLE\n", id); - shdc[id].phase = 1; - shdc[id].status = READY_STAT | DRQ_STAT | (shdc[id].status & ERR_STAT); - return; - case CDROM_PHASE_COMPLETE: - scsi_hd_log("SCSI HD %i: PHASE_COMPLETE\n", id); - shdc[id].status = READY_STAT; - shdc[id].phase = 3; - shdc[id].packet_status = 0xFF; - return; - case CDROM_PHASE_DATA_OUT: - scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT\n", id); - shdc[id].status = READY_STAT | DRQ_STAT | (shdc[id].status & ERR_STAT); - shdc[id].phase = 0; - return; - case CDROM_PHASE_DATA_OUT_DMA: - scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT_DMA\n", id); - scsi_hd_phase_data_out(id); - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - shdc[id].status = READY_STAT; - shdc[id].phase = 3; - return; - case CDROM_PHASE_DATA_IN: - scsi_hd_log("SCSI HD %i: PHASE_DATA_IN\n", id); - shdc[id].status = READY_STAT | DRQ_STAT | (shdc[id].status & ERR_STAT); - shdc[id].phase = 2; - return; - case CDROM_PHASE_DATA_IN_DMA: - scsi_hd_log("SCSI HD %i: PHASE_DATA_IN_DMA\n", id); - scsi_hd_phase_data_in(id); - shdc[id].packet_status = CDROM_PHASE_COMPLETE; - shdc[id].status = READY_STAT; - shdc[id].phase = 3; - return; - case CDROM_PHASE_ERROR: - scsi_hd_log("SCSI HD %i: PHASE_ERROR\n", id); - shdc[id].status = READY_STAT | ERR_STAT; - shdc[id].phase = 3; - return; - } -} diff --git a/backup code/scsi/scsi_disk - Cópia.h b/backup code/scsi/scsi_disk - Cópia.h deleted file mode 100644 index f41906d46..000000000 --- a/backup code/scsi/scsi_disk - Cópia.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - * - * Emulation of SCSI fixed and removable disks. - * - * Version: @(#)scsi_disk.h 1.0.4 2018/04/24 - * - * Author: Miran Grca, - * Copyright 2017,2018 Miran Grca. - */ - - -typedef struct { - /* Stuff for SCSI hard disks. */ - uint8_t status, phase, - error, - current_cdb[16], - sense[256]; - - uint16_t request_length; - - int requested_blocks, block_total, - packet_status, callback, - block_descriptor_len, - total_length, do_page_save; - - uint32_t sector_pos, sector_len, - packet_len; - - uint64_t current_page_code; - - uint8_t *temp_buffer; -} scsi_hard_disk_t; - - -extern scsi_hard_disk_t shdc[HDD_NUM]; -extern FILE *shdf[HDD_NUM]; - - -extern void scsi_loadhd(int scsi_id, int scsi_lun, int id); - -int scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len); diff --git a/backup code/scsi/scsi_null.c b/backup code/scsi/scsi_null.c deleted file mode 100644 index a7fa72cf9..000000000 --- a/backup code/scsi/scsi_null.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * 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. - * - * Emulation of SCSI null device, used for invalid LUN's where - * LUN 0 is valid. - * - * Version: @(#)scsi_null.c 1.0.0 2018/06/12 - * - * Author: Miran Grca, - * - * Copyright 2017,2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../device.h" -#include "../nvr.h" -#include "../disk/hdd.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../plat.h" -#include "../ui.h" -#include "scsi.h" -#include "../cdrom/cdrom.h" -#include "scsi_device.h" - - -/* Bits of 'status' */ -#define ERR_STAT 0x01 -#define DRQ_STAT 0x08 /* Data request */ -#define DSC_STAT 0x10 -#define SERVICE_STAT 0x10 -#define READY_STAT 0x40 -#define BUSY_STAT 0x80 - -/* Bits of 'error' */ -#define ABRT_ERR 0x04 /* Command aborted */ -#define MCR_ERR 0x08 /* Media change request */ - -#define MAX_BLOCKS_AT_ONCE 340 - - -#define scsi_null_sense_key scsi_null_device_sense[2] -#define scsi_null_asc scsi_null_device_sense[12] -#define scsi_null_ascq scsi_null_device_sense[13] - - -static uint8_t status, phase, packet_status, error, command, packet_len, sense_desc; -static int64_t callback; -static uint8_t null_id, null_lun; -static uint8_t *temp_buffer; - - - -#ifdef ENABLE_SCSI_NULL_LOG -int scsi_null_do_log = ENABLE_SCSI_NULL_LOG; -#endif - - -static void -scsi_null_log(const char *fmt, ...) -{ -#ifdef ENABLE_SCSI_NULL_LOG - va_list ap; - - if (scsi_null_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -/* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ -int -scsi_null_err_stat_to_scsi(void) -{ - if (status & ERR_STAT) - return SCSI_STATUS_CHECK_CONDITION; - else - return SCSI_STATUS_OK; -} - - -static void -scsi_null_command_common(void) -{ - status = BUSY_STAT; - phase = 1; - if (packet_status == CDROM_PHASE_COMPLETE) { - scsi_null_callback(); - callback = 0LL; - } else - callback = -1LL; /* Speed depends on SCSI controller */ -} - - -static void -scsi_null_command_complete(void) -{ - packet_status = CDROM_PHASE_COMPLETE; - scsi_null_command_common(); -} - - -static void -scsi_null_command_read_dma(void) -{ - packet_status = CDROM_PHASE_DATA_IN_DMA; - scsi_null_command_common(); -} - - -static void -scsi_null_data_command_finish(int len, int block_len, int alloc_len, int direction) -{ - if (alloc_len >= 0) { - if (alloc_len < len) - len = alloc_len; - } - if (len == 0) - scsi_null_command_complete(); - else { - if (direction == 0) - scsi_null_command_read_dma(); - else - fatal("SCSI NULL device write command\n"); - } -} - - -static void -scsi_null_set_phase(uint8_t phase) -{ - SCSIDevices[null_id][null_lun].Phase = phase; -} - - -static void -scsi_null_cmd_error(void) -{ - scsi_null_set_phase(SCSI_PHASE_STATUS); - error = ((scsi_null_sense_key & 0xf) << 4) | ABRT_ERR; - status = READY_STAT | ERR_STAT; - phase = 3; - packet_status = 0x80; - callback = 50 * SCSI_TIME; - scsi_null_log("SCSI NULL: ERROR: %02X/%02X/%02X\n", scsi_null_sense_key, scsi_null_asc, scsi_null_ascq); -} - - -static void -scsi_null_invalid_lun(void) -{ - scsi_null_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_null_asc = ASC_INV_LUN; - scsi_null_ascq = 0; - scsi_null_set_phase(SCSI_PHASE_STATUS); - scsi_null_cmd_error(); -} - - -static void -scsi_null_invalid_field(void) -{ - scsi_null_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_null_asc = ASC_INV_FIELD_IN_CMD_PACKET; - scsi_null_ascq = 0; - scsi_null_cmd_error(); - status = 0x53; -} - - -void -scsi_null_request_sense(uint8_t *buffer, uint8_t alloc_length, int desc) -{ - /*Will return 18 bytes of 0*/ - if (alloc_length != 0) { - memset(buffer, 0, alloc_length); - if (!desc) - if (alloc_length <= 18) - memcpy(buffer, scsi_null_device_sense, alloc_length); - else { - memset(buffer, 0x00, alloc_length); - memcpy(buffer, scsi_null_device_sense, 18); - } - else { - buffer[1] = scsi_null_sense_key; - buffer[2] = scsi_null_asc; - buffer[3] = scsi_null_ascq; - } - } else - return; - - buffer[0] = 0x70; - - scsi_null_log("SCSI NULL: Reporting sense: %02X %02X %02X\n", buffer[2], buffer[12], buffer[13]); - - /* Clear the sense stuff as per the spec. */ - scsi_null_sense_key = scsi_null_asc = scsi_null_ascq = 0x00; -} - - -void -scsi_null_request_sense_for_scsi(uint8_t *buffer, uint8_t alloc_length) -{ - scsi_null_request_sense(buffer, alloc_length, 0); -} - - -void -scsi_null_command(uint8_t *cdb) -{ - int32_t *BufLen; - uint32_t len; - int max_len; - unsigned idx = 0; - unsigned size_idx, preamble_len; - - BufLen = &SCSIDevices[null_id][null_lun].BufferLength; - - status &= ~ERR_STAT; - packet_len = 0; - - scsi_null_set_phase(SCSI_PHASE_STATUS); - - command = cdb[0]; - switch (cdb[0]) { - case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ - sense_desc = cdb [1]; - - if ((*BufLen == -1) || (cdb[4] < *BufLen)) - *BufLen = cdb[4]; - - if (*BufLen < cdb[4]) - cdb[4] = *BufLen; - - len = (cdb[1] & 1) ? 8 : 18; - - scsi_null_set_phase(SCSI_PHASE_DATA_IN); - scsi_null_data_command_finish(len, len, cdb[4], 0); - break; - -#if 0 - case GPCMD_INQUIRY: - max_len = cdb[3]; - max_len <<= 8; - max_len |= cdb[4]; - - if ((!max_len) || (*BufLen == 0)) { - scsi_null_set_phase(SCSI_PHASE_STATUS); - packet_status = CDROM_PHASE_COMPLETE; - callback = 20 * SCSI_TIME; - break; - } - - if (cdb[1] & 1) { - scsi_null_invalid_field(); - return; - } else { - temp_buffer = malloc(1024); - - preamble_len = 5; - size_idx = 4; - - memset(temp_buffer, 0, 8); - temp_buffer[0] = (3 << 5); /*Invalid*/ - temp_buffer[1] = 0; /*Fixed*/ - temp_buffer[2] = 0x02; /*SCSI-2 compliant*/ - temp_buffer[3] = 0x02; - temp_buffer[4] = 31; - temp_buffer[6] = 1; /* 16-bit transfers supported */ - temp_buffer[7] = 0x20; /* Wide bus supported */ - - ide_padstr8(temp_buffer + 8, 8, EMU_NAME); /* Vendor */ - ide_padstr8(temp_buffer + 16, 16, "INVALID"); /* Product */ - ide_padstr8(temp_buffer + 32, 4, EMU_VERSION); /* Revision */ - idx = 36; - - if (max_len == 96) { - temp_buffer[4] = 91; - idx = 96; - } - } - - temp_buffer[size_idx] = idx - preamble_len; - len=idx; - - if (len > max_len) - len = max_len; - - if ((*BufLen == -1) || (len < *BufLen)) - *BufLen = len; - - if (len > *BufLen) - len = *BufLen; - - scsi_null_set_phase(SCSI_PHASE_DATA_IN); - scsi_null_data_command_finish(len, len, max_len, 0); - break; -#endif - - default: - scsi_null_invalid_lun(); - break; - } -} - - -static void -scsi_null_phase_data_in(void) -{ - uint8_t *hdbufferb = SCSIDevices[null_id][null_lun].CmdBuffer; - int32_t *BufLen = &SCSIDevices[null_id][null_lun].BufferLength; - - if (!*BufLen) { - scsi_null_log("scsi_null_phase_data_in(): Buffer length is 0\n"); - scsi_null_set_phase(SCSI_PHASE_STATUS); - - return; - } - - switch (command) { - case GPCMD_REQUEST_SENSE: - scsi_null_log("SCSI NULL: %08X, %08X\n", hdbufferb, *BufLen); - scsi_null_request_sense(hdbufferb, *BufLen, sense_desc & 1); - break; -#if 0 - case GPCMD_INQUIRY: - memcpy(hdbufferb, temp_buffer, *BufLen); - free(temp_buffer); - temp_buffer = NULL; - scsi_null_log("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", - hdbufferb[0], hdbufferb[1], hdbufferb[2], hdbufferb[3], hdbufferb[4], hdbufferb[5], hdbufferb[6], hdbufferb[7], - hdbufferb[8], hdbufferb[9], hdbufferb[10], hdbufferb[11], hdbufferb[12], hdbufferb[13], hdbufferb[14], hdbufferb[15]); - break; -#endif - default: - fatal("SCSI NULL: Bad Command for phase 2 (%02X)\n", command); - break; - } - - scsi_null_set_phase(SCSI_PHASE_STATUS); -} - - -void -scsi_null_callback(void) -{ - switch(packet_status) { - case CDROM_PHASE_IDLE: - scsi_null_log("SCSI NULL: PHASE_IDLE\n"); - phase = 1; - status = READY_STAT | DRQ_STAT | (status & ERR_STAT); - return; - case CDROM_PHASE_COMPLETE: - scsi_null_log("SCSI NULL: PHASE_COMPLETE\n"); - status = READY_STAT; - phase = 3; - packet_status = 0xFF; - return; - case CDROM_PHASE_DATA_IN_DMA: - scsi_null_log("SCSI NULL: PHASE_DATA_IN_DMA\n"); - scsi_null_phase_data_in(); - packet_status = CDROM_PHASE_COMPLETE; - status = READY_STAT; - phase = 3; - return; - case CDROM_PHASE_ERROR: - scsi_null_log("SCSI NULL: PHASE_ERROR\n"); - status = READY_STAT | ERR_STAT; - phase = 3; - return; - } -} - - -void -scsi_null_set_location(uint8_t id, uint8_t lun) -{ - null_id = id; - null_lun = lun; -} diff --git a/backup code/video - Cópia/vid_ati18800.c b/backup code/video - Cópia/vid_ati18800.c deleted file mode 100644 index 01614c299..000000000 --- a/backup code/video - Cópia/vid_ati18800.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * 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. - * - * ATI 18800 emulation (VGA Edge-16) - * - * Version: @(#)vid_ati18800.c 1.0.12 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "video.h" -#include "vid_ati18800.h" -#include "vid_ati_eeprom.h" -#include "vid_svga.h" -#include "vid_svga_render.h" - - -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) -#define BIOS_ROM_PATH_WONDER L"roms/video/ati18800/VGA_Wonder_V3-1.02.bin" -#endif -#define BIOS_ROM_PATH_VGA88 L"roms/video/ati18800/vga88.bin" -#define BIOS_ROM_PATH_EDGE16 L"roms/video/ati18800/vgaedge16.vbi" - -enum { -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) - ATI18800_WONDER = 0, - ATI18800_VGA88, - ATI18800_EDGE16 -#else - ATI18800_VGA88 = 0, - ATI18800_EDGE16 -#endif -}; - - -typedef struct ati18800_t -{ - svga_t svga; - ati_eeprom_t eeprom; - - rom_t bios_rom; - - uint8_t regs[256]; - int index; -} ati18800_t; - - -static void ati18800_out(uint16_t addr, uint8_t val, void *p) -{ - ati18800_t *ati18800 = (ati18800_t *)p; - svga_t *svga = &ati18800->svga; - uint8_t old; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x1ce: - ati18800->index = val; - break; - case 0x1cf: - ati18800->regs[ati18800->index] = val; - switch (ati18800->index) - { - case 0xb0: - svga_recalctimings(svga); - case 0xb2: - case 0xbe: - if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/ - { - svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; - } - else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; - break; - case 0xb3: - ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1); - break; - } - break; - - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80) && !(ati18800->regs[0xb4] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80) && !(ati18800->regs[0xb4] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); -} - -static uint8_t ati18800_in(uint16_t addr, void *p) -{ - ati18800_t *ati18800 = (ati18800_t *)p; - svga_t *svga = &ati18800->svga; - uint8_t temp; - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; - - switch (addr) - { - case 0x1ce: - temp = ati18800->index; - break; - case 0x1cf: - switch (ati18800->index) - { - case 0xb7: - temp = ati18800->regs[ati18800->index] & ~8; - if (ati_eeprom_read(&ati18800->eeprom)) - temp |= 8; - break; - default: - temp = ati18800->regs[ati18800->index]; - break; - } - break; - - case 0x3D4: - temp = svga->crtcreg; - break; - case 0x3D5: - temp = svga->crtc[svga->crtcreg]; - break; - default: - temp = svga_in(addr, svga); - break; - } - return temp; -} - -static void ati18800_recalctimings(svga_t *svga) -{ - ati18800_t *ati18800 = (ati18800_t *)svga->p; - - if(svga->crtc[0x17] & 4) - { - svga->vtotal <<= 1; - svga->dispend <<= 1; - svga->vsyncstart <<= 1; - svga->split <<= 1; - svga->vblankstart <<= 1; - } - - if (!svga->scrblank && (ati18800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/ - { - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - svga->rowoffset <<= 1; - svga->ma <<= 1; - } -} - -static void *ati18800_init(const device_t *info) -{ - ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); - memset(ati18800, 0, sizeof(ati18800_t)); - - switch (info->local) { -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) - case ATI18800_WONDER: -#endif - default: -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) - rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_WONDER, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; -#endif - case ATI18800_VGA88: - rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_VGA88, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - case ATI18800_EDGE16: - rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EDGE16, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - }; - - svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/ - ati18800_recalctimings, - ati18800_in, ati18800_out, - NULL, - NULL); - - io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); - io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); - - ati18800->svga.miscout = 1; - - ati_eeprom_load(&ati18800->eeprom, L"ati18800.nvr", 0); - - return ati18800; -} - -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) -static int ati18800_wonder_available(void) -{ - return rom_present(BIOS_ROM_PATH_WONDER); -} -#endif - -static int ati18800_vga88_available(void) -{ - return rom_present(BIOS_ROM_PATH_VGA88); -} - -static int ati18800_available(void) -{ - return rom_present(BIOS_ROM_PATH_EDGE16); -} - -static void ati18800_close(void *p) -{ - ati18800_t *ati18800 = (ati18800_t *)p; - - svga_close(&ati18800->svga); - - free(ati18800); -} - -static void ati18800_speed_changed(void *p) -{ - ati18800_t *ati18800 = (ati18800_t *)p; - - svga_recalctimings(&ati18800->svga); -} - -static void ati18800_force_redraw(void *p) -{ - ati18800_t *ati18800 = (ati18800_t *)p; - - ati18800->svga.fullchange = changeframecount; -} - -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) -const device_t ati18800_wonder_device = -{ - "ATI-18800", - DEVICE_ISA, ATI18800_WONDER, - ati18800_init, - ati18800_close, - NULL, - ati18800_wonder_available, - ati18800_speed_changed, - ati18800_force_redraw, - NULL -}; -#endif - -const device_t ati18800_vga88_device = -{ - "ATI-18800-1", - DEVICE_ISA, ATI18800_VGA88, - ati18800_init, - ati18800_close, - NULL, - ati18800_vga88_available, - ati18800_speed_changed, - ati18800_force_redraw, - NULL -}; - -const device_t ati18800_device = -{ - "ATI-18800-5", - DEVICE_ISA, ATI18800_EDGE16, - ati18800_init, - ati18800_close, - NULL, - ati18800_available, - ati18800_speed_changed, - ati18800_force_redraw, - NULL -}; diff --git a/backup code/video - Cópia/vid_ati18800.h b/backup code/video - Cópia/vid_ati18800.h deleted file mode 100644 index b41facab3..000000000 --- a/backup code/video - Cópia/vid_ati18800.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t ati18800_wonder_device; -extern const device_t ati18800_vga88_device; -extern const device_t ati18800_device; diff --git a/backup code/video - Cópia/vid_ati28800.c b/backup code/video - Cópia/vid_ati28800.c deleted file mode 100644 index e8fda8302..000000000 --- a/backup code/video - Cópia/vid_ati28800.c +++ /dev/null @@ -1,645 +0,0 @@ -/* - * 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. - * - * ATI 28800 emulation (VGA Charger and Korean VGA) - * - * Version: @(#)vid_ati28800.c 1.0.19 2018/05/20 - * - * Authors: Sarah Walker, - * Miran Grca, - * greatpsycho, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2018 greatpsycho. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" -#include "video.h" -#include "vid_ati28800.h" -#include "vid_ati_eeprom.h" -#include "vid_svga.h" -#include "vid_svga_render.h" - - -#define BIOS_ATIKOR_PATH L"roms/video/ati28800/atikorvga.bin" -#define FONT_ATIKOR_PATH L"roms/video/ati28800/ati_ksc5601.rom" - -#define BIOS_VGAXL_EVEN_PATH L"roms/video/ati28800/xleven.bin" -#define BIOS_VGAXL_ODD_PATH L"roms/video/ati28800/xlodd.bin" - -#if defined(DEV_BRANCH) && defined(USE_XL24) -#define BIOS_XL24_EVEN_PATH L"roms/video/ati28800/112-14318-102.bin" -#define BIOS_XL24_ODD_PATH L"roms/video/ati28800/112-14319-102.bin" -#endif - -#define BIOS_ROM_PATH L"roms/video/ati28800/bios.bin" - - -typedef struct ati28800_t -{ - svga_t svga; - ati_eeprom_t eeprom; - - rom_t bios_rom; - - uint8_t regs[256]; - int index; - - uint32_t memory; - - uint8_t port_03dd_val; - uint16_t get_korean_font_kind; - int in_get_korean_font_kind_set; - int get_korean_font_enabled; - int get_korean_font_index; - uint16_t get_korean_font_base; - int ksc5601_mode_enabled; -} ati28800_t; - - -#ifdef ENABLE_ATI28800_LOG -int ati28800_do_log = ENABLE_ATI28800_LOG; -#endif - - -static void -ati28800_log(const char *fmt, ...) -{ -#ifdef ENABLE_ATI28800_LOG - va_list ap; - - if (ati28800_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void ati28800_out(uint16_t addr, uint8_t val, void *p) -{ - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint8_t old; - - ati28800_log("ati28800_out : %04X %02X %04X:%04X\n", addr, val, CS, cpu_state.pc); - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) - addr ^= 0x60; - - switch (addr) - { - case 0x1ce: - ati28800->index = val; - break; - case 0x1cf: - old=ati28800->regs[ati28800->index]; - ati28800->regs[ati28800->index] = val; - switch (ati28800->index) - { - case 0xb2: - case 0xbe: - if (ati28800->regs[0xbe] & 8) /*Read/write bank mode*/ - { - svga->read_bank = ((ati28800->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000; - } - else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000; - break; - case 0xb3: - ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1); - break; - case 0xb6: - if((old ^ val) & 0x10) svga_recalctimings(svga); - break; - case 0xb8: - if((old ^ val) & 0x40) svga_recalctimings(svga); - break; - case 0xb9: - if((old ^ val) & 2) svga_recalctimings(svga); - } - break; - - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); -} - -void ati28800k_out(uint16_t addr, uint8_t val, void *p) -{ - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint16_t oldaddr = addr; - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) - addr ^= 0x60; - - switch (addr) - { - case 0x1CF: - if(ati28800->index == 0xBF && ((ati28800->regs[0xBF] ^ val) & 0x20)) - { - ati28800->ksc5601_mode_enabled = val & 0x20; - svga_recalctimings(svga); - - } - ati28800_out(oldaddr, val, p); - break; - case 0x3DD: - ati28800->port_03dd_val = val; - if(val == 1) ati28800->get_korean_font_enabled = 0; - if(ati28800->in_get_korean_font_kind_set) - { - ati28800->get_korean_font_kind = (val << 8) | (ati28800->get_korean_font_kind & 0xFF); - ati28800->get_korean_font_enabled = 1; - ati28800->get_korean_font_index = 0; - ati28800->in_get_korean_font_kind_set = 0; - } - break; - case 0x3DE: - ati28800->in_get_korean_font_kind_set = 0; - if(ati28800->get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) - { - if((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) - fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20].chr[ati28800->get_korean_font_index] = val; - ati28800->get_korean_font_index++; - ati28800->get_korean_font_index &= 0x1F; - } - else - - { - switch(ati28800->port_03dd_val) - { - case 0x10: - ati28800->get_korean_font_base = ((val & 0x7F) << 7) | (ati28800->get_korean_font_base & 0x7F); - break; - case 8: - ati28800->get_korean_font_base = (ati28800->get_korean_font_base & 0x3F80) | (val & 0x7F); - break; - case 1: - ati28800->get_korean_font_kind = (ati28800->get_korean_font_kind & 0xFF00) | val; - if(val & 2) - ati28800->in_get_korean_font_kind_set = 1; - break; - } - break; - } - default: - ati28800_out(oldaddr, val, p); - break; - } -} - -static uint8_t ati28800_in(uint16_t addr, void *p) -{ - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint8_t temp; - - if (addr != 0x3da) ati28800_log("ati28800_in : %04X ", addr); - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; - - switch (addr) - { - case 0x1ce: - temp = ati28800->index; - break; - case 0x1cf: - switch (ati28800->index) - { - case 0xb0: - if (ati28800->memory == 256) - return 0x08; - else if (ati28800->memory == 512) - return 0x10; - else - return 0x18; - break; - - case 0xb7: - temp = ati28800->regs[ati28800->index] & ~8; - if (ati_eeprom_read(&ati28800->eeprom)) - temp |= 8; - break; - - default: - temp = ati28800->regs[ati28800->index]; - break; - } - break; - - case 0x3c2: - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) - temp = 0; - else - temp = 0x10; - break; - case 0x3D4: - temp = svga->crtcreg; - break; - case 0x3D5: - temp = svga->crtc[svga->crtcreg]; - break; - default: - temp = svga_in(addr, svga); - break; - } - if (addr != 0x3da) ati28800_log("%02X %04X:%04X\n", temp, CS,cpu_state.pc); - return temp; -} - -uint8_t ati28800k_in(uint16_t addr, void *p) -{ - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint16_t oldaddr = addr; - uint8_t temp = 0xFF; - - if (addr != 0x3da) ati28800_log("ati28800k_in : %04X ", addr); - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; - - switch (addr) - { - case 0x3DE: - if (ati28800->get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) - { - switch(ati28800->get_korean_font_kind >> 8) - { - case 4: /* ROM font */ - temp = fontdatksc5601[ati28800->get_korean_font_base].chr[ati28800->get_korean_font_index++]; - break; - case 2: /* User defined font */ - if((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) - temp = fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20].chr[ati28800->get_korean_font_index]; - else - temp = 0xFF; - ati28800->get_korean_font_index++; - break; - default: - break; - } - ati28800->get_korean_font_index &= 0x1F; - } - break; - default: - temp = ati28800_in(oldaddr, p); - break; - } - if (addr != 0x3da) ati28800_log("%02X %04X:%04X\n", temp, CS,cpu_state.pc); - return temp; -} - -static void ati28800_recalctimings(svga_t *svga) -{ - ati28800_t *ati28800 = (ati28800_t *)svga->p; - - switch(((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) - { - case 0x00: svga->clock = cpuclock / 42954000.0; break; - case 0x01: svga->clock = cpuclock / 48771000.0; break; - case 0x03: svga->clock = cpuclock / 36000000.0; break; - case 0x04: svga->clock = cpuclock / 50350000.0; break; - case 0x05: svga->clock = cpuclock / 56640000.0; break; - case 0x07: svga->clock = cpuclock / 44900000.0; break; - case 0x08: svga->clock = cpuclock / 30240000.0; break; - case 0x09: svga->clock = cpuclock / 32000000.0; break; - case 0x0A: svga->clock = cpuclock / 37500000.0; break; - case 0x0B: svga->clock = cpuclock / 39000000.0; break; - case 0x0C: svga->clock = cpuclock / 40000000.0; break; - case 0x0D: svga->clock = cpuclock / 56644000.0; break; - case 0x0E: svga->clock = cpuclock / 75000000.0; break; - case 0x0F: svga->clock = cpuclock / 65000000.0; break; - default: break; - } - - if(ati28800->regs[0xb8] & 0x40) svga->clock *= 2; - - - if (ati28800->regs[0xb6] & 0x10) - { - svga->hdisp <<= 1; - svga->htotal <<= 1; - svga->rowoffset <<= 1; - } - - if(svga->crtc[0x17] & 4) - { - svga->vtotal <<= 1; - svga->dispend <<= 1; - svga->vsyncstart <<= 1; - svga->split <<= 1; - svga->vblankstart <<= 1; - } - - if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/ - { - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - svga->rowoffset <<= 1; - svga->ma <<= 1; - } -} - -void ati28800k_recalctimings(svga_t *svga) -{ - ati28800_t *ati28800 = (ati28800_t *) svga->p; - - ati28800_recalctimings(svga); - - if (svga->render == svga_render_text_80 && ati28800->ksc5601_mode_enabled) - { - svga->render = svga_render_text_80_ksc5601; - } -} - -void * -ati28800k_init(const device_t *info) -{ - ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); - memset(ati28800, 0, sizeof(ati28800_t)); - - ati28800->memory = device_get_config_int("memory"); - - ati28800->port_03dd_val = 0; - ati28800->get_korean_font_base = 0; - ati28800->get_korean_font_index = 0; - ati28800->get_korean_font_enabled = 0; - ati28800->get_korean_font_kind = 0; - ati28800->in_get_korean_font_kind_set = 0; - ati28800->ksc5601_mode_enabled = 0; - - rom_init(&ati28800->bios_rom, BIOS_ATIKOR_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - loadfont(FONT_ATIKOR_PATH, 6); - - svga_init(&ati28800->svga, ati28800, ati28800->memory << 10, /*Memory size, default 512KB*/ - ati28800k_recalctimings, - ati28800k_in, ati28800k_out, - NULL, - NULL); - - io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); - io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); - - ati28800->svga.miscout = 1; - - ati_eeprom_load(&ati28800->eeprom, L"atikorvga.nvr", 0); - - return ati28800; -} - -static void * -ati28800_init(const device_t *info) -{ - ati28800_t *ati; - ati = malloc(sizeof(ati28800_t)); - memset(ati, 0x00, sizeof(ati28800_t)); - - ati->memory = device_get_config_int("memory"); - - switch(info->local) { - case GFX_VGAWONDERXL: - rom_init_interleaved(&ati->bios_rom, - BIOS_VGAXL_EVEN_PATH, - BIOS_VGAXL_ODD_PATH, - 0xc0000, 0x10000, 0xffff, - 0, MEM_MAPPING_EXTERNAL); - break; - -#if defined(DEV_BRANCH) && defined(USE_XL24) - case GFX_VGAWONDERXL24: - rom_init_interleaved(&ati->bios_rom, - BIOS_XL24_EVEN_PATH, - BIOS_XL24_ODD_PATH, - 0xc0000, 0x10000, 0xffff, - 0, MEM_MAPPING_EXTERNAL); - break; -#endif - - default: - rom_init(&ati->bios_rom, - BIOS_ROM_PATH, - 0xc0000, 0x8000, 0x7fff, - 0, MEM_MAPPING_EXTERNAL); - break; - } - - svga_init(&ati->svga, ati, ati->memory << 10, /*default: 512kb*/ - ati28800_recalctimings, - ati28800_in, ati28800_out, - NULL, - NULL); - - io_sethandler(0x01ce, 2, - ati28800_in, NULL, NULL, - ati28800_out, NULL, NULL, ati); - io_sethandler(0x03c0, 32, - ati28800_in, NULL, NULL, - ati28800_out, NULL, NULL, ati); - - ati->svga.miscout = 1; - - ati_eeprom_load(&ati->eeprom, L"ati28800.nvr", 0); - - return(ati); -} - - -static int -ati28800_available(void) -{ - return(rom_present(BIOS_ROM_PATH)); -} - - -static int -ati28800k_available() -{ - return ((rom_present(BIOS_ATIKOR_PATH) && rom_present(FONT_ATIKOR_PATH))); -} - - -static int -compaq_ati28800_available(void) -{ - return((rom_present(BIOS_VGAXL_EVEN_PATH) && rom_present(BIOS_VGAXL_ODD_PATH))); -} - - -#if defined(DEV_BRANCH) && defined(USE_XL24) -static int -ati28800_wonderxl24_available(void) -{ - return((rom_present(BIOS_XL24_EVEN_PATH) && rom_present(BIOS_XL24_ODD_PATH))); -} -#endif - - -static void -ati28800_close(void *priv) -{ - ati28800_t *ati = (ati28800_t *)priv; - - svga_close(&ati->svga); - - free(ati); -} - - -static void -ati28800_speed_changed(void *p) -{ - ati28800_t *ati28800 = (ati28800_t *)p; - - svga_recalctimings(&ati28800->svga); -} - - -static void -ati28800_force_redraw(void *priv) -{ - ati28800_t *ati = (ati28800_t *)priv; - - ati->svga.fullchange = changeframecount; -} - - -static const device_config_t ati28800_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 512, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "1024 kB", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -#if defined(DEV_BRANCH) && defined(USE_XL24) -static const device_config_t ati28800_wonderxl_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 512, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "1 MB", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; -#endif - -const device_t ati28800_device = -{ - "ATI-28800", - DEVICE_ISA, - 0, - ati28800_init, ati28800_close, NULL, - ati28800_available, - ati28800_speed_changed, - ati28800_force_redraw, - ati28800_config -}; - -const device_t ati28800k_device = -{ - "ATI Korean VGA", - DEVICE_ISA, - 0, - ati28800k_init, ati28800_close, NULL, - ati28800k_available, - ati28800_speed_changed, - ati28800_force_redraw, - ati28800_config -}; - -const device_t compaq_ati28800_device = -{ - "Compaq ATI-28800", - DEVICE_ISA, - GFX_VGAWONDERXL, - ati28800_init, ati28800_close, NULL, - compaq_ati28800_available, - ati28800_speed_changed, - ati28800_force_redraw, - ati28800_config -}; - -#if defined(DEV_BRANCH) && defined(USE_XL24) -const device_t ati28800_wonderxl24_device = -{ - "ATI-28800 (VGA Wonder XL24)", - DEVICE_ISA, - GFX_VGAWONDERXL24, - ati28800_init, ati28800_close, NULL, - ati28800_wonderxl24_available, - ati28800_speed_changed, - ati28800_force_redraw, - ati28800_wonderxl_config -}; -#endif diff --git a/backup code/video - Cópia/vid_ati28800.h b/backup code/video - Cópia/vid_ati28800.h deleted file mode 100644 index 9db0fa7bc..000000000 --- a/backup code/video - Cópia/vid_ati28800.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -extern const device_t ati28800_device; -extern const device_t ati28800k_device; -extern const device_t compaq_ati28800_device; -#if defined(DEV_BRANCH) && defined(USE_XL24) -extern const device_t ati28800_wonderxl24_device; -#endif diff --git a/backup code/video - Cópia/vid_ati68860_ramdac.c b/backup code/video - Cópia/vid_ati68860_ramdac.c deleted file mode 100644 index 89a9827d3..000000000 --- a/backup code/video - Cópia/vid_ati68860_ramdac.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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. - * - * ATI 68860 RAMDAC emulation (for Mach64) - * - * ATI 68860/68880 Truecolor DACs: - * REG08 (R/W): - * bit 0-? Always 2 ?? - * - * REG0A (R/W): - * bit 0-? Always 1Dh ?? - * - * REG0B (R/W): (GMR ?) - * bit 0-7 Mode. 82h: 4bpp, 83h: 8bpp, - * A0h: 15bpp, A1h: 16bpp, C0h: 24bpp, - * E3h: 32bpp (80h for VGA modes ?) - * - * REG0C (R/W): Device Setup Register A - * bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT - * 2-3 Depends on Video memory (= VRAM width ?) . - * 1: Less than 1Mb, 2: 1Mb, 3: > 1Mb - * 5-6 Always set ? - * 7 If set can remove "snow" in some cases - * (A860_Delay_L ?) ?? - * - * Version: @(#)vid_ati68860.c 1.0.3 2017/11/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_ati68860_ramdac.h" -#include "vid_svga_render.h" - - -void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga) -{ - switch (addr) - { - case 0: - svga_out(0x3c8, val, svga); - break; - case 1: - svga_out(0x3c9, val, svga); - break; - case 2: - svga_out(0x3c6, val, svga); - break; - case 3: - svga_out(0x3c7, val, svga); - break; - default: - ramdac->regs[addr & 0xf] = val; - switch (addr & 0xf) - { - case 0x4: - ramdac->dac_write = val; - ramdac->dac_pos = 0; - break; - case 0x5: - switch (ramdac->dac_pos) - { - case 0: - ramdac->dac_r = val; - ramdac->dac_pos++; - break; - case 1: - ramdac->dac_g = val; - ramdac->dac_pos++; - break; - case 2: - if (ramdac->dac_write > 1) - break; - ramdac->pal[ramdac->dac_write].r = ramdac->dac_r; - ramdac->pal[ramdac->dac_write].g = ramdac->dac_g; - ramdac->pal[ramdac->dac_write].b = val; - if (ramdac->ramdac_type == RAMDAC_8BIT) - ramdac->pallook[ramdac->dac_write] = makecol32(ramdac->pal[ramdac->dac_write].r, ramdac->pal[ramdac->dac_write].g, ramdac->pal[ramdac->dac_write].b); - else - ramdac->pallook[ramdac->dac_write] = makecol32((ramdac->pal[ramdac->dac_write].r & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].g & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].b & 0x3f) * 4); - ramdac->dac_pos = 0; - ramdac->dac_write = (ramdac->dac_write + 1) & 255; - break; - } - break; - - case 0xb: - switch (val) - { - case 0x82: - ramdac->render = svga_render_4bpp_highres; - break; - case 0x83: - ramdac->render = svga_render_8bpp_highres; - break; - case 0xa0: case 0xb0: - ramdac->render = svga_render_15bpp_highres; - break; - case 0xa1: case 0xb1: - ramdac->render = svga_render_16bpp_highres; - break; - case 0xc0: case 0xd0: - ramdac->render = svga_render_24bpp_highres; - break; - case 0xe2: case 0xf7: - ramdac->render = svga_render_32bpp_highres; - break; - case 0xe3: - ramdac->render = svga_render_ABGR8888_highres; - break; - case 0xf2: - ramdac->render = svga_render_RGBA8888_highres; - break; - default: - ramdac->render = svga_render_8bpp_highres; - break; - } - break; - case 0xc: - svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT); - break; - } - break; - } -} - -uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga) -{ - uint8_t ret = 0; - switch (addr) - { - case 0: - ret = svga_in(0x3c8, svga); - break; - case 1: - ret = svga_in(0x3c9, svga); - break; - case 2: - ret = svga_in(0x3c6, svga); - break; - case 3: - ret = svga_in(0x3c7, svga); - break; - case 4: case 8: - ret = 2; - break; - case 6: case 0xa: - ret = 0x1d; - break; - case 0xf: - ret = 0xd0; - break; - - default: - ret = ramdac->regs[addr & 0xf]; - break; - } - return ret; -} - -void ati68860_ramdac_init(ati68860_ramdac_t *ramdac) -{ - ramdac->render = svga_render_8bpp_highres; -} - -void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type) -{ - int c; - - if (ramdac->ramdac_type != type) - { - ramdac->ramdac_type = type; - - for (c = 0; c < 2; c++) - { - if (ramdac->ramdac_type == RAMDAC_8BIT) - ramdac->pallook[c] = makecol32(ramdac->pal[c].r, ramdac->pal[c].g, ramdac->pal[c].b); - else - ramdac->pallook[c] = makecol32((ramdac->pal[c].r & 0x3f) * 4, (ramdac->pal[c].g & 0x3f) * 4, (ramdac->pal[c].b & 0x3f) * 4); - } - } -} diff --git a/backup code/video - Cópia/vid_ati68860_ramdac.h b/backup code/video - Cópia/vid_ati68860_ramdac.h deleted file mode 100644 index c71376b42..000000000 --- a/backup code/video - Cópia/vid_ati68860_ramdac.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -typedef struct ati68860_ramdac_t -{ - uint8_t regs[16]; - void (*render)(struct svga_t *svga); - - int dac_write, dac_pos; - int dac_r, dac_g; - PALETTE pal; - uint32_t pallook[2]; - - int ramdac_type; -} ati68860_ramdac_t; - -void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga); -uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga); -void ati68860_ramdac_init(ati68860_ramdac_t *ramdac); -void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type); diff --git a/backup code/video - Cópia/vid_ati_eeprom.c b/backup code/video - Cópia/vid_ati_eeprom.c deleted file mode 100644 index 4bcd9d702..000000000 --- a/backup code/video - Cópia/vid_ati_eeprom.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * 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 EEPROM on select ATI cards. - * - * Version: @(#)vid_ati_eeprom.c 1.0.2 2018/04/11 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../nvr.h" -#include "vid_ati_eeprom.h" - - -enum -{ - EEPROM_IDLE, - EEPROM_WAIT, - EEPROM_OPCODE, - EEPROM_INPUT, - EEPROM_OUTPUT -}; - -enum -{ - EEPROM_OP_EW = 4, - EEPROM_OP_WRITE = 5, - EEPROM_OP_READ = 6, - EEPROM_OP_ERASE = 7, - - EEPROM_OP_WRALMAIN = -1 -}; - -enum -{ - EEPROM_OP_EWDS = 0, - EEPROM_OP_WRAL = 1, - EEPROM_OP_ERAL = 2, - EEPROM_OP_EWEN = 3 -}; - -void ati_eeprom_load(ati_eeprom_t *eeprom, wchar_t *fn, int type) -{ - FILE *f; - eeprom->type = type; - wcscpy(eeprom->fn, fn); - f = nvr_fopen(eeprom->fn, L"rb"); - if (!f) - { - memset(eeprom->data, 0, eeprom->type ? 512 : 128); - return; - } - fread(eeprom->data, 1, eeprom->type ? 512 : 128, f); - fclose(f); -} - -void ati_eeprom_save(ati_eeprom_t *eeprom) -{ - FILE *f = nvr_fopen(eeprom->fn, L"wb"); - if (!f) return; - fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f); - fclose(f); -} - -void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) -{ - int c; - if (!ena) - { - eeprom->out = 1; - } - if (clk && !eeprom->oldclk) - { - if (ena && !eeprom->oldena) - { - eeprom->state = EEPROM_WAIT; - eeprom->opcode = 0; - eeprom->count = 3; - eeprom->out = 1; - } - else if (ena) - { - switch (eeprom->state) - { - case EEPROM_WAIT: - if (!dat) - break; - eeprom->state = EEPROM_OPCODE; - /* fall through */ - case EEPROM_OPCODE: - eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0); - eeprom->count--; - if (!eeprom->count) - { - switch (eeprom->opcode) - { - case EEPROM_OP_WRITE: - eeprom->count = eeprom->type ? 24 : 22; - eeprom->state = EEPROM_INPUT; - eeprom->dat = 0; - break; - case EEPROM_OP_READ: - eeprom->count = eeprom->type ? 8 : 6; - eeprom->state = EEPROM_INPUT; - eeprom->dat = 0; - break; - case EEPROM_OP_EW: - eeprom->count = 2; - eeprom->state = EEPROM_INPUT; - eeprom->dat = 0; - break; - case EEPROM_OP_ERASE: - eeprom->count = eeprom->type ? 8 : 6; - eeprom->state = EEPROM_INPUT; - eeprom->dat = 0; - break; - } - } - break; - - case EEPROM_INPUT: - eeprom->dat = (eeprom->dat << 1) | (dat ? 1 : 0); - eeprom->count--; - if (!eeprom->count) - { - switch (eeprom->opcode) - { - case EEPROM_OP_WRITE: - if (!eeprom->wp) - { - eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = eeprom->dat & 0xffff; - ati_eeprom_save(eeprom); - } - eeprom->state = EEPROM_IDLE; - eeprom->out = 1; - break; - - case EEPROM_OP_READ: - eeprom->count = 17; - eeprom->state = EEPROM_OUTPUT; - eeprom->dat = eeprom->data[eeprom->dat]; - break; - case EEPROM_OP_EW: - switch (eeprom->dat) - { - case EEPROM_OP_EWDS: - eeprom->wp = 1; - break; - case EEPROM_OP_WRAL: - eeprom->opcode = EEPROM_OP_WRALMAIN; - eeprom->count = 20; - break; - case EEPROM_OP_ERAL: - if (!eeprom->wp) - { - memset(eeprom->data, 0xff, 128); - ati_eeprom_save(eeprom); - } - break; - case EEPROM_OP_EWEN: - eeprom->wp = 0; - break; - } - eeprom->state = EEPROM_IDLE; - eeprom->out = 1; - break; - - case EEPROM_OP_ERASE: - if (!eeprom->wp) - { - eeprom->data[eeprom->dat] = 0xffff; - ati_eeprom_save(eeprom); - } - eeprom->state = EEPROM_IDLE; - eeprom->out = 1; - break; - - case EEPROM_OP_WRALMAIN: - if (!eeprom->wp) - { - for (c = 0; c < 256; c++) - eeprom->data[c] = eeprom->dat; - ati_eeprom_save(eeprom); - } - eeprom->state = EEPROM_IDLE; - eeprom->out = 1; - break; - } - } - break; - } - } - eeprom->oldena = ena; - } - else if (!clk && eeprom->oldclk) - { - if (ena) - { - switch (eeprom->state) - { - case EEPROM_OUTPUT: - eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0; - eeprom->dat <<= 1; - eeprom->count--; - if (!eeprom->count) - { - eeprom->state = EEPROM_IDLE; - } - break; - } - } - } - eeprom->oldclk = clk; -} - -int ati_eeprom_read(ati_eeprom_t *eeprom) -{ - return eeprom->out; -} - diff --git a/backup code/video - Cópia/vid_ati_eeprom.h b/backup code/video - Cópia/vid_ati_eeprom.h deleted file mode 100644 index 786ae0c8b..000000000 --- a/backup code/video - Cópia/vid_ati_eeprom.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -typedef struct ati_eeprom_t -{ - uint16_t data[256]; - - int oldclk, oldena; - int opcode, state, count, out; - int wp; - uint32_t dat; - int type; - - wchar_t fn[256]; -} ati_eeprom_t; - -void ati_eeprom_load(ati_eeprom_t *eeprom, wchar_t *fn, int type); -void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat); -int ati_eeprom_read(ati_eeprom_t *eeprom); diff --git a/backup code/video - Cópia/vid_ati_mach64.c b/backup code/video - Cópia/vid_ati_mach64.c deleted file mode 100644 index 0418013a9..000000000 --- a/backup code/video - Cópia/vid_ati_mach64.c +++ /dev/null @@ -1,3513 +0,0 @@ -/* - * 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. - * - * ATi Mach64 graphics card emulation. - * - * Version: @(#)vid_ati_mach64.c 1.0.21 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../plat.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_svga_render.h" -#include "vid_ati68860_ramdac.h" -#include "vid_ati_eeprom.h" -#include "vid_ics2595.h" - -#ifdef CLAMP -#undef CLAMP -#endif - -#define BIOS_ROM_PATH L"roms/video/mach64/bios.bin" -#define BIOS_ISA_ROM_PATH L"roms/video/mach64/M64-1994.VBI" -#define BIOS_VLB_ROM_PATH L"roms/video/mach64/mach64_vlb_vram.bin" -#define BIOS_ROMVT2_PATH L"roms/video/mach64/atimach64vt2pci.bin" - - -#define FIFO_SIZE 65536 -#define FIFO_MASK (FIFO_SIZE - 1) -#define FIFO_ENTRY_SIZE (1 << 31) - -#define FIFO_ENTRIES (mach64->fifo_write_idx - mach64->fifo_read_idx) -#define FIFO_FULL ((mach64->fifo_write_idx - mach64->fifo_read_idx) >= FIFO_SIZE) -#define FIFO_EMPTY (mach64->fifo_read_idx == mach64->fifo_write_idx) - -#define FIFO_TYPE 0xff000000 -#define FIFO_ADDR 0x00ffffff - -enum -{ - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_WORD = (0x02 << 24), - FIFO_WRITE_DWORD = (0x03 << 24) -}; - -typedef struct -{ - uint32_t addr_type; - uint32_t val; -} fifo_entry_t; - -enum -{ - MACH64_GX = 0, - MACH64_VT2 -}; - -typedef struct mach64_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t mmio_mapping; - mem_mapping_t mmio_linear_mapping; - mem_mapping_t mmio_linear_mapping_2; - - ati68860_ramdac_t ramdac; - ati_eeprom_t eeprom; - ics2595_t ics2595; - svga_t svga; - - rom_t bios_rom; - - uint8_t regs[256]; - int index; - - int type, pci; - - uint8_t pci_regs[256]; - uint8_t int_line; - int card; - - int bank_r[2]; - int bank_w[2]; - - uint32_t vram_size; - uint32_t vram_mask; - - uint32_t config_cntl; - - uint32_t context_load_cntl; - uint32_t context_mask; - - uint32_t crtc_gen_cntl; - uint8_t crtc_int_cntl; - uint32_t crtc_h_total_disp; - uint32_t crtc_v_sync_strt_wid; - uint32_t crtc_v_total_disp; - uint32_t crtc_off_pitch; - - uint32_t clock_cntl; - - uint32_t clr_cmp_clr; - uint32_t clr_cmp_cntl; - uint32_t clr_cmp_mask; - - uint32_t cur_horz_vert_off; - uint32_t cur_horz_vert_posn; - uint32_t cur_offset; - - uint32_t dac_cntl; - - uint32_t dp_bkgd_clr; - uint32_t dp_frgd_clr; - uint32_t dp_mix; - uint32_t dp_pix_width; - uint32_t dp_src; - - uint32_t dst_bres_lnth; - uint32_t dst_bres_dec; - uint32_t dst_bres_err; - uint32_t dst_bres_inc; - - uint32_t dst_cntl; - uint32_t dst_height_width; - uint32_t dst_off_pitch; - uint32_t dst_y_x; - - uint32_t gen_test_cntl; - - uint32_t gui_traj_cntl; - - uint32_t host_cntl; - - uint32_t mem_cntl; - - uint32_t ovr_clr; - uint32_t ovr_wid_left_right; - uint32_t ovr_wid_top_bottom; - - uint32_t pat_cntl; - uint32_t pat_reg0, pat_reg1; - - uint32_t sc_left_right, sc_top_bottom; - - uint32_t scratch_reg0, scratch_reg1; - - uint32_t src_cntl; - uint32_t src_off_pitch; - uint32_t src_y_x; - uint32_t src_y_x_start; - uint32_t src_height1_width1, src_height2_width2; - - - uint32_t linear_base, old_linear_base; - uint32_t io_base; - - struct - { - int op; - - int dst_x, dst_y; - int dst_x_start, dst_y_start; - int src_x, src_y; - int src_x_start, src_y_start; - int xinc, yinc; - int x_count, y_count; - int src_x_count, src_y_count; - int src_width1, src_height1; - int src_width2, src_height2; - uint32_t src_offset, src_pitch; - uint32_t dst_offset, dst_pitch; - int mix_bg, mix_fg; - int source_bg, source_fg, source_mix; - int source_host; - int dst_width, dst_height; - int busy; - int pattern[8][8]; - int sc_left, sc_right, sc_top, sc_bottom; - int dst_pix_width, src_pix_width, host_pix_width; - int dst_size, src_size, host_size; - - uint32_t dp_bkgd_clr; - uint32_t dp_frgd_clr; - - uint32_t clr_cmp_clr; - uint32_t clr_cmp_mask; - int clr_cmp_fn; - int clr_cmp_src; - - int err; - int poly_draw; - } accel; - - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; - - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; - - int blitter_busy; - uint64_t blitter_time; - uint64_t status_time; - - uint16_t pci_id; - uint32_t config_chip_id; - uint32_t block_decoded_io; - int use_block_decoded_io; - - int pll_addr; - uint8_t pll_regs[16]; - double pll_freq[4]; - - uint32_t config_stat0; - - uint32_t cur_clr0, cur_clr1; - - uint32_t overlay_dat[1024]; - uint32_t overlay_graphics_key_clr, overlay_graphics_key_msk; - uint32_t overlay_video_key_clr, overlay_video_key_msk; - uint32_t overlay_key_cntl; - uint32_t overlay_scale_inc; - uint32_t overlay_scale_cntl; - uint32_t overlay_y_x_start, overlay_y_x_end; - - uint32_t scaler_height_width; - int scaler_format; - int scaler_update; - - uint32_t buf_offset[2], buf_pitch[2]; - - int overlay_v_acc; -} mach64_t; - -enum -{ - SRC_BG = 0, - SRC_FG = 1, - SRC_HOST = 2, - SRC_BLITSRC = 3, - SRC_PAT = 4 -}; - -enum -{ - MONO_SRC_1 = 0, - MONO_SRC_PAT = 1, - MONO_SRC_HOST = 2, - MONO_SRC_BLITSRC = 3 -}; - -enum -{ - BPP_1 = 0, - BPP_4 = 1, - BPP_8 = 2, - BPP_15 = 3, - BPP_16 = 4, - BPP_32 = 5 -}; - -enum -{ - OP_RECT, - OP_LINE -}; - -enum -{ - SRC_PATT_EN = 1, - SRC_PATT_ROT_EN = 2, - SRC_LINEAR_EN = 4 -}; - -enum -{ - DP_BYTE_PIX_ORDER = (1 << 24) -}; - -#define WIDTH_1BIT 3 - -static int mach64_width[8] = {WIDTH_1BIT, 0, 0, 1, 1, 2, 2, 0}; - -enum -{ - DST_X_DIR = 0x01, - DST_Y_DIR = 0x02, - DST_Y_MAJOR = 0x04, - DST_X_TILE = 0x08, - DST_Y_TILE = 0x10, - DST_LAST_PEL = 0x20, - DST_POLYGON_EN = 0x40, - DST_24_ROT_EN = 0x80 -}; - -enum -{ - HOST_BYTE_ALIGN = (1 << 0) -}; - -void mach64_write(uint32_t addr, uint8_t val, void *priv); -void mach64_writew(uint32_t addr, uint16_t val, void *priv); -void mach64_writel(uint32_t addr, uint32_t val, void *priv); -uint8_t mach64_read(uint32_t addr, void *priv); -uint16_t mach64_readw(uint32_t addr, void *priv); -uint32_t mach64_readl(uint32_t addr, void *priv); -void mach64_updatemapping(mach64_t *mach64); -void mach64_recalctimings(svga_t *svga); -void mach64_start_fill(mach64_t *mach64); -void mach64_start_line(mach64_t *mach64); -void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64); -void mach64_load_context(mach64_t *mach64); - -uint8_t mach64_ext_readb(uint32_t addr, void *priv); -uint16_t mach64_ext_readw(uint32_t addr, void *priv); -uint32_t mach64_ext_readl(uint32_t addr, void *priv); -void mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv); -void mach64_ext_writew(uint32_t addr, uint16_t val, void *priv); -void mach64_ext_writel(uint32_t addr, uint32_t val, void *priv); - - -#ifdef ENABLE_MACH64_LOG -int mach64_do_log = ENABLE_MACH64_LOG; -#endif - - -static void -mach64_log(const char *fmt, ...) -{ -#ifdef ENABLE_MACH64_LOG - va_list ap; - - if (mach64_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -void mach64_out(uint16_t addr, uint8_t val, void *p) -{ - mach64_t *mach64 = p; - svga_t *svga = &mach64->svga; - uint8_t old; - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x1ce: - mach64->index = val; - break; - case 0x1cf: - mach64->regs[mach64->index & 0x3f] = val; - if ((mach64->index & 0x3f) == 0x36) - mach64_recalctimings(svga); - break; - - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - if (mach64->type == MACH64_GX) - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, svga); - else - svga_out(addr, val, svga); - return; - - case 0x3cf: - if (svga->gdcaddr == 6) - { - uint8_t old_val = svga->gdcreg[6]; - svga->gdcreg[6] = val; - if ((svga->gdcreg[6] & 0xc) != (old_val & 0xc)) - mach64_updatemapping(mach64); - return; - } - break; - - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg > 0x18) - return; - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - - if (old!=val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); -} - -uint8_t mach64_in(uint16_t addr, void *p) -{ - mach64_t *mach64 = p; - svga_t *svga = &mach64->svga; - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) - addr ^= 0x60; - - switch (addr) - { - case 0x1ce: - return mach64->index; - case 0x1cf: - return mach64->regs[mach64->index & 0x3f]; - - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - if (mach64->type == MACH64_GX) - return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, svga); - return svga_in(addr, svga); - - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - if (svga->crtcreg > 0x18) - return 0xff; - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); -} - -void mach64_recalctimings(svga_t *svga) -{ - mach64_t *mach64 = (mach64_t *)svga->p; - - if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) - { - svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1; - svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1; - svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; - svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; - svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; - svga->rowoffset = (mach64->crtc_off_pitch >> 22); - svga->clock = cpuclock / mach64->ics2595.output_clock; - svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2; - svga->linedbl = svga->rowcount = 0; - svga->split = 0xffffff; - svga->vblankstart = svga->dispend; - svga->rowcount = mach64->crtc_gen_cntl & 1; - svga->rowoffset <<= 1; - if (mach64->type == MACH64_GX) - svga->render = mach64->ramdac.render; - switch ((mach64->crtc_gen_cntl >> 8) & 7) - { - case 1: - if (mach64->type != MACH64_GX) - svga->render = svga_render_4bpp_highres; - svga->hdisp *= 8; - break; - case 2: - if (mach64->type != MACH64_GX) - svga->render = svga_render_8bpp_highres; - svga->hdisp *= 8; - svga->rowoffset /= 2; - break; - case 3: - if (mach64->type != MACH64_GX) - svga->render = svga_render_15bpp_highres; - svga->hdisp *= 8; - break; - case 4: - if (mach64->type != MACH64_GX) - svga->render = svga_render_16bpp_highres; - svga->hdisp *= 8; - break; - case 5: - if (mach64->type != MACH64_GX) - svga->render = svga_render_24bpp_highres; - svga->hdisp *= 8; - svga->rowoffset = (svga->rowoffset * 3) / 2; - break; - case 6: - if (mach64->type != MACH64_GX) - svga->render = svga_render_32bpp_highres; - svga->hdisp *= 8; - svga->rowoffset *= 2; - break; - } - - svga->vram_display_mask = mach64->vram_mask; - } - else - { - svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff; - } -} - -void mach64_updatemapping(mach64_t *mach64) -{ - svga_t *svga = &mach64->svga; - - if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) - { - mach64_log("Update mapping - PCI disabled\n"); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&mach64->linear_mapping); - mem_mapping_disable(&mach64->mmio_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping_2); - return; - } - - mem_mapping_disable(&mach64->mmio_mapping); - switch (svga->gdcreg[6] & 0xc) - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); - mem_mapping_set_p(&mach64->svga.mapping, mach64); - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - mem_mapping_enable(&mach64->mmio_mapping); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); - mem_mapping_set_p(&mach64->svga.mapping, mach64); - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); - mem_mapping_set_p(&mach64->svga.mapping, svga); - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); - mem_mapping_set_p(&mach64->svga.mapping, svga); - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - if (mach64->linear_base) - { - if (mach64->type == MACH64_GX) - { - if ((mach64->config_cntl & 3) == 2) - { - /*8 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); - } - else - { - /*4 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000); - } - } - else - { - /*2*8 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000); - } - } - else - { - mem_mapping_disable(&mach64->linear_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping_2); - } -} - -static void mach64_update_irqs(mach64_t *mach64) -{ - if (!mach64->pci) - { - return; - } - - if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024)) - pci_set_irq(mach64->card, PCI_INTA); - else - pci_clear_irq(mach64->card, PCI_INTA); -} - -static __inline void wake_fifo_thread(mach64_t *mach64) -{ - thread_set_event(mach64->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ -} - -static void mach64_wait_fifo_idle(mach64_t *mach64) -{ - while (!FIFO_EMPTY) - { - wake_fifo_thread(mach64); - thread_wait_event(mach64->fifo_not_full_event, 1); - } -} - -#define READ8(addr, var) switch ((addr) & 3) \ - { \ - case 0: ret = (var) & 0xff; break; \ - case 1: ret = ((var) >> 8) & 0xff; break; \ - case 2: ret = ((var) >> 16) & 0xff; break; \ - case 3: ret = ((var) >> 24) & 0xff; break; \ - } - -#define WRITE8(addr, var, val) switch ((addr) & 3) \ - { \ - case 0: var = (var & 0xffffff00) | (val); break; \ - case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \ - case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \ - case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ - } - -static void mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) -{ - switch (addr & 0x3ff) - { - case 0x100: case 0x101: case 0x102: case 0x103: - WRITE8(addr, mach64->dst_off_pitch, val); - break; - case 0x104: case 0x105: case 0x11c: case 0x11d: - WRITE8(addr + 2, mach64->dst_y_x, val); - break; - case 0x108: case 0x109: - WRITE8(addr, mach64->dst_y_x, val); - break; - case 0x10c: case 0x10d: case 0x10e: case 0x10f: - WRITE8(addr, mach64->dst_y_x, val); - break; - case 0x110: case 0x111: - WRITE8(addr + 2, mach64->dst_height_width, val); - break; - case 0x114: case 0x115: - case 0x118: case 0x119: case 0x11a: case 0x11b: - case 0x11e: case 0x11f: - WRITE8(addr, mach64->dst_height_width, val); - case 0x113: - if (((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || - (addr & 0x3ff) == 0x113) && !(val & 0x80)) - { - mach64_start_fill(mach64); - mach64_log("%i %i %i %i %i %08x\n", (mach64->dst_height_width & 0x7ff), (mach64->dst_height_width & 0x7ff0000), - ((mach64->dp_src & 7) != SRC_HOST), (((mach64->dp_src >> 8) & 7) != SRC_HOST), - (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST), mach64->dp_src); - if ((mach64->dst_height_width & 0x7ff) && (mach64->dst_height_width & 0x7ff0000) && - ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && - (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) - mach64_blit(0, -1, mach64); - } - break; - - case 0x120: case 0x121: case 0x122: case 0x123: - WRITE8(addr, mach64->dst_bres_lnth, val); - if ((addr & 0x3ff) == 0x123 && !(val & 0x80)) - { - mach64_start_line(mach64); - - if ((mach64->dst_bres_lnth & 0x7fff) && - ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && - (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) - mach64_blit(0, -1, mach64); - } - break; - case 0x124: case 0x125: case 0x126: case 0x127: - WRITE8(addr, mach64->dst_bres_err, val); - break; - case 0x128: case 0x129: case 0x12a: case 0x12b: - WRITE8(addr, mach64->dst_bres_inc, val); - break; - case 0x12c: case 0x12d: case 0x12e: case 0x12f: - WRITE8(addr, mach64->dst_bres_dec, val); - break; - - case 0x130: case 0x131: case 0x132: case 0x133: - WRITE8(addr, mach64->dst_cntl, val); - break; - - case 0x180: case 0x181: case 0x182: case 0x183: - WRITE8(addr, mach64->src_off_pitch, val); - break; - case 0x184: case 0x185: - WRITE8(addr, mach64->src_y_x, val); - break; - case 0x188: case 0x189: - WRITE8(addr + 2, mach64->src_y_x, val); - break; - case 0x18c: case 0x18d: case 0x18e: case 0x18f: - WRITE8(addr, mach64->src_y_x, val); - break; - case 0x190: case 0x191: - WRITE8(addr + 2, mach64->src_height1_width1, val); - break; - case 0x194: case 0x195: - WRITE8(addr, mach64->src_height1_width1, val); - break; - case 0x198: case 0x199: case 0x19a: case 0x19b: - WRITE8(addr, mach64->src_height1_width1, val); - break; - case 0x19c: case 0x19d: - WRITE8(addr, mach64->src_y_x_start, val); - break; - case 0x1a0: case 0x1a1: - WRITE8(addr + 2, mach64->src_y_x_start, val); - break; - case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7: - WRITE8(addr, mach64->src_y_x_start, val); - break; - case 0x1a8: case 0x1a9: - WRITE8(addr + 2, mach64->src_height2_width2, val); - break; - case 0x1ac: case 0x1ad: - WRITE8(addr, mach64->src_height2_width2, val); - break; - case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3: - WRITE8(addr, mach64->src_height2_width2, val); - break; - - case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7: - WRITE8(addr, mach64->src_cntl, val); - break; - - case 0x200: case 0x201: case 0x202: case 0x203: - case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20a: case 0x20b: - case 0x20c: case 0x20d: case 0x20e: case 0x20f: - case 0x210: case 0x211: case 0x212: case 0x213: - case 0x214: case 0x215: case 0x216: case 0x217: - case 0x218: case 0x219: case 0x21a: case 0x21b: - case 0x21c: case 0x21d: case 0x21e: case 0x21f: - case 0x220: case 0x221: case 0x222: case 0x223: - case 0x224: case 0x225: case 0x226: case 0x227: - case 0x228: case 0x229: case 0x22a: case 0x22b: - case 0x22c: case 0x22d: case 0x22e: case 0x22f: - case 0x230: case 0x231: case 0x232: case 0x233: - case 0x234: case 0x235: case 0x236: case 0x237: - case 0x238: case 0x239: case 0x23a: case 0x23b: - case 0x23c: case 0x23d: case 0x23e: case 0x23f: - mach64_blit(val, 8, mach64); - break; - - case 0x240: case 0x241: case 0x242: case 0x243: - WRITE8(addr, mach64->host_cntl, val); - break; - - case 0x280: case 0x281: case 0x282: case 0x283: - WRITE8(addr, mach64->pat_reg0, val); - break; - case 0x284: case 0x285: case 0x286: case 0x287: - WRITE8(addr, mach64->pat_reg1, val); - break; - - case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9: - WRITE8(addr, mach64->sc_left_right, val); - break; - case 0x2a4: case 0x2a5: - addr += 2; - case 0x2aa: case 0x2ab: - WRITE8(addr, mach64->sc_left_right, val); - break; - - case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5: - WRITE8(addr, mach64->sc_top_bottom, val); - break; - case 0x2b0: case 0x2b1: - addr += 2; - case 0x2b6: case 0x2b7: - WRITE8(addr, mach64->sc_top_bottom, val); - break; - - case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3: - WRITE8(addr, mach64->dp_bkgd_clr, val); - break; - case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: - WRITE8(addr, mach64->dp_frgd_clr, val); - break; - - case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3: - WRITE8(addr, mach64->dp_pix_width, val); - break; - case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7: - WRITE8(addr, mach64->dp_mix, val); - break; - case 0x2d8: case 0x2d9: case 0x2da: case 0x2db: - WRITE8(addr, mach64->dp_src, val); - break; - - case 0x300: case 0x301: case 0x302: case 0x303: - WRITE8(addr, mach64->clr_cmp_clr, val); - break; - case 0x304: case 0x305: case 0x306: case 0x307: - WRITE8(addr, mach64->clr_cmp_mask, val); - break; - case 0x308: case 0x309: case 0x30a: case 0x30b: - WRITE8(addr, mach64->clr_cmp_cntl, val); - break; - - case 0x320: case 0x321: case 0x322: case 0x323: - WRITE8(addr, mach64->context_mask, val); - break; - - case 0x330: case 0x331: - WRITE8(addr, mach64->dst_cntl, val); - break; - case 0x332: - WRITE8(addr - 2, mach64->src_cntl, val); - break; - case 0x333: - WRITE8(addr - 3, mach64->pat_cntl, val & 7); - if (val & 0x10) - mach64->host_cntl |= HOST_BYTE_ALIGN; - else - mach64->host_cntl &= ~HOST_BYTE_ALIGN; - break; - } -} -static void mach64_accel_write_fifo_w(mach64_t *mach64, uint32_t addr, uint16_t val) -{ - switch (addr & 0x3fe) - { - case 0x200: case 0x202: case 0x204: case 0x206: - case 0x208: case 0x20a: case 0x20c: case 0x20e: - case 0x210: case 0x212: case 0x214: case 0x216: - case 0x218: case 0x21a: case 0x21c: case 0x21e: - case 0x220: case 0x222: case 0x224: case 0x226: - case 0x228: case 0x22a: case 0x22c: case 0x22e: - case 0x230: case 0x232: case 0x234: case 0x236: - case 0x238: case 0x23a: case 0x23c: case 0x23e: - mach64_blit(val, 16, mach64); - break; - - default: - mach64_accel_write_fifo(mach64, addr, val); - mach64_accel_write_fifo(mach64, addr + 1, val >> 8); - break; - } -} -static void mach64_accel_write_fifo_l(mach64_t *mach64, uint32_t addr, uint32_t val) -{ - switch (addr & 0x3fc) - { - case 0x32c: - mach64->context_load_cntl = val; - if (val & 0x30000) - mach64_load_context(mach64); - break; - - case 0x200: case 0x204: case 0x208: case 0x20c: - case 0x210: case 0x214: case 0x218: case 0x21c: - case 0x220: case 0x224: case 0x228: case 0x22c: - case 0x230: case 0x234: case 0x238: case 0x23c: - if (mach64->accel.source_host || (mach64->dp_pix_width & DP_BYTE_PIX_ORDER)) - mach64_blit(val, 32, mach64); - else - mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32, mach64); - break; - - default: - mach64_accel_write_fifo_w(mach64, addr, val); - mach64_accel_write_fifo_w(mach64, addr + 2, val >> 16); - break; - } -} - -static void fifo_thread(void *param) -{ - mach64_t *mach64 = (mach64_t *)param; - - while (1) - { - thread_set_event(mach64->fifo_not_full_event); - thread_wait_event(mach64->wake_fifo_thread, -1); - thread_reset_event(mach64->wake_fifo_thread); - mach64->blitter_busy = 1; - while (!FIFO_EMPTY) - { - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_read_idx & FIFO_MASK]; - - switch (fifo->addr_type & FIFO_TYPE) - { - case FIFO_WRITE_BYTE: - mach64_accel_write_fifo(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_WORD: - mach64_accel_write_fifo_w(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_DWORD: - mach64_accel_write_fifo_l(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - } - - mach64->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; - - if (FIFO_ENTRIES > 0xe000) - thread_set_event(mach64->fifo_not_full_event); - - end_time = plat_timer_read(); - mach64->blitter_time += end_time - start_time; - } - mach64->blitter_busy = 0; - } -} - -static void mach64_queue(mach64_t *mach64, uint32_t addr, uint32_t val, uint32_t type) -{ - fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_write_idx & FIFO_MASK]; - - if (FIFO_FULL) - { - thread_reset_event(mach64->fifo_not_full_event); - if (FIFO_FULL) - { - thread_wait_event(mach64->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } - - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; - - mach64->fifo_write_idx++; - - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(mach64); -} - -void mach64_cursor_dump(mach64_t *mach64) -{ - return; -} - -void mach64_start_fill(mach64_t *mach64) -{ - int x, y; - - mach64->accel.dst_x = 0; - mach64->accel.dst_y = 0; - mach64->accel.dst_x_start = (mach64->dst_y_x >> 16) & 0xfff; - mach64->accel.dst_y_start = mach64->dst_y_x & 0xfff; - - mach64->accel.dst_width = (mach64->dst_height_width >> 16) & 0x1fff; - mach64->accel.dst_height = mach64->dst_height_width & 0x1fff; - - if (((mach64->dp_src >> 16) & 7) == MONO_SRC_BLITSRC) - { - if (mach64->accel.dst_width & 7) - mach64->accel.dst_width = (mach64->accel.dst_width & ~7) + 8; - } - - mach64->accel.x_count = mach64->accel.dst_width; - - mach64->accel.src_x = 0; - mach64->accel.src_y = 0; - mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; - mach64->accel.src_y_start = mach64->src_y_x & 0xfff; - if (mach64->src_cntl & SRC_LINEAR_EN) - mach64->accel.src_x_count = 0x7ffffff; /*Essentially infinite*/ - else - mach64->accel.src_x_count = (mach64->src_height1_width1 >> 16) & 0x7fff; - if (!(mach64->src_cntl & SRC_PATT_EN)) - mach64->accel.src_y_count = 0x7ffffff; /*Essentially infinite*/ - else - mach64->accel.src_y_count = mach64->src_height1_width1 & 0x1fff; - - mach64->accel.src_width1 = (mach64->src_height1_width1 >> 16) & 0x7fff; - mach64->accel.src_height1 = mach64->src_height1_width1 & 0x1fff; - mach64->accel.src_width2 = (mach64->src_height2_width2 >> 16) & 0x7fff; - mach64->accel.src_height2 = mach64->src_height2_width2 & 0x1fff; - - mach64_log("src %i %i %i %i %08X %08X\n", mach64->accel.src_x_count, - mach64->accel.src_y_count, - mach64->accel.src_width1, - mach64->accel.src_height1, - mach64->src_height1_width1, - mach64->src_height2_width2); - - mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; - mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; - - mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; - mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; - - mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; - mach64->accel.mix_bg = mach64->dp_mix & 0x1f; - - mach64->accel.source_bg = mach64->dp_src & 7; - mach64->accel.source_fg = (mach64->dp_src >> 8) & 7; - mach64->accel.source_mix = (mach64->dp_src >> 16) & 7; - - mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; - mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; - mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; - - mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; - mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; - mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; - - if (mach64->accel.src_size == WIDTH_1BIT) - mach64->accel.src_offset <<= 3; - else - mach64->accel.src_offset >>= mach64->accel.src_size; - - if (mach64->accel.dst_size == WIDTH_1BIT) - mach64->accel.dst_offset <<= 3; - else - mach64->accel.dst_offset >>= mach64->accel.dst_size; - - mach64->accel.xinc = (mach64->dst_cntl & DST_X_DIR) ? 1 : -1; - mach64->accel.yinc = (mach64->dst_cntl & DST_Y_DIR) ? 1 : -1; - - mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - - - for (y = 0; y < 8; y++) - { - for (x = 0; x < 8; x++) - { - uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; - mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1; - } - } - - mach64->accel.sc_left = mach64->sc_left_right & 0x1fff; - mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; - mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; - mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; - - mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; - mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; - - mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask; - mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask; - mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7; - mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24); - - mach64->accel.poly_draw = 0; - - mach64->accel.busy = 1; - mach64_log("mach64_start_fill : dst %i, %i src %i, %i size %i, %i src pitch %i offset %X dst pitch %i offset %X scissor %i %i %i %i src_fg %i mix %02X %02X\n", mach64->accel.dst_x_start, mach64->accel.dst_y_start, mach64->accel.src_x_start, mach64->accel.src_y_start, mach64->accel.dst_width, mach64->accel.dst_height, mach64->accel.src_pitch, mach64->accel.src_offset, mach64->accel.dst_pitch, mach64->accel.dst_offset, mach64->accel.sc_left, mach64->accel.sc_right, mach64->accel.sc_top, mach64->accel.sc_bottom, mach64->accel.source_fg, mach64->accel.mix_fg, mach64->accel.mix_bg); - - mach64->accel.op = OP_RECT; -} - -void mach64_start_line(mach64_t *mach64) -{ - int x, y; - - mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff; - mach64->accel.dst_y = mach64->dst_y_x & 0xfff; - - mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff; - mach64->accel.src_y = mach64->src_y_x & 0xfff; - - mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; - mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; - - mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; - mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; - - mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; - mach64->accel.mix_bg = mach64->dp_mix & 0x1f; - - mach64->accel.source_bg = mach64->dp_src & 7; - mach64->accel.source_fg = (mach64->dp_src >> 8) & 7; - mach64->accel.source_mix = (mach64->dp_src >> 16) & 7; - - mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; - mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; - mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; - - mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; - mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; - mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; - - if (mach64->accel.src_size == WIDTH_1BIT) - mach64->accel.src_offset <<= 3; - else - mach64->accel.src_offset >>= mach64->accel.src_size; - - if (mach64->accel.dst_size == WIDTH_1BIT) - mach64->accel.dst_offset <<= 3; - else - mach64->accel.dst_offset >>= mach64->accel.dst_size; - -/* mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width]; - mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/ - - mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - - for (y = 0; y < 8; y++) - { - for (x = 0; x < 8; x++) - { - uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; - mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1; - } - } - - mach64->accel.sc_left = mach64->sc_left_right & 0x1fff; - mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; - mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; - mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; - - mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; - mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; - - mach64->accel.x_count = mach64->dst_bres_lnth & 0x7fff; - mach64->accel.err = (mach64->dst_bres_err & 0x3ffff) | ((mach64->dst_bres_err & 0x40000) ? 0xfffc0000 : 0); - - mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask; - mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask; - mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7; - mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24); - - mach64->accel.busy = 1; - mach64_log("mach64_start_line\n"); - - mach64->accel.op = OP_LINE; -} - -#define READ(addr, dat, width) if (width == 0) dat = svga->vram[((addr)) & mach64->vram_mask]; \ - else if (width == 1) dat = *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask]; \ - else if (width == 2) dat = *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask]; \ - else if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) dat = (svga->vram[((addr) >> 3) & mach64->vram_mask] >> ((addr) & 7)) & 1; \ - else dat = (svga->vram[((addr) >> 3) & mach64->vram_mask] >> (7 - ((addr) & 7))) & 1; - -#define MIX switch (mix ? mach64->accel.mix_fg : mach64->accel.mix_bg) \ - { \ - case 0x0: dest_dat = ~dest_dat; break; \ - case 0x1: dest_dat = 0; break; \ - case 0x2: dest_dat = 0xffffffff; break; \ - case 0x3: dest_dat = dest_dat; break; \ - case 0x4: dest_dat = ~src_dat; break; \ - case 0x5: dest_dat = src_dat ^ dest_dat; break; \ - case 0x6: dest_dat = ~(src_dat ^ dest_dat); break; \ - case 0x7: dest_dat = src_dat; break; \ - case 0x8: dest_dat = ~(src_dat & dest_dat); break; \ - case 0x9: dest_dat = ~src_dat | dest_dat; break; \ - case 0xa: dest_dat = src_dat | ~dest_dat; break; \ - case 0xb: dest_dat = src_dat | dest_dat; break; \ - case 0xc: dest_dat = src_dat & dest_dat; break; \ - case 0xd: dest_dat = src_dat & ~dest_dat; break; \ - case 0xe: dest_dat = ~src_dat & dest_dat; break; \ - case 0xf: dest_dat = ~(src_dat | dest_dat); break; \ - } - -#define WRITE(addr, width) if (width == 0) \ - { \ - svga->vram[(addr) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[((addr) & mach64->vram_mask) >> 12] = changeframecount; \ - } \ - else if (width == 1) \ - { \ - *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \ - } \ - else if (width == 2) \ - { \ - *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \ - } \ - else \ - { \ - if (dest_dat & 1) { \ - if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ - svga->vram[((addr) >> 3) & mach64->vram_mask] |= 1 << ((addr) & 7); \ - else \ - svga->vram[((addr) >> 3) & mach64->vram_mask] |= 1 << (7 - ((addr) & 7)); \ - } else { \ - if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ - svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << ((addr) & 7)); \ - else \ - svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << (7 - ((addr) & 7)));\ - } \ - svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = changeframecount; \ - } - -void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) -{ - svga_t *svga = &mach64->svga; - int cmp_clr = 0; - - if (!mach64->accel.busy) - { - mach64_log("mach64_blit : return as not busy\n"); - return; - } - switch (mach64->accel.op) - { - case OP_RECT: - while (count) - { - uint32_t src_dat, dest_dat; - uint32_t host_dat = 0; - int mix = 0; - int dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff; - int dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0xfff; - int src_x; - int src_y = (mach64->accel.src_y + mach64->accel.src_y_start) & 0xfff; - - if (mach64->src_cntl & SRC_LINEAR_EN) - src_x = mach64->accel.src_x; - else - src_x = (mach64->accel.src_x + mach64->accel.src_x_start) & 0xfff; - - if (mach64->accel.source_host) - { - host_dat = cpu_dat; - switch (mach64->accel.host_size) - { - case 0: - cpu_dat >>= 8; - count -= 8; - break; - case 1: - cpu_dat >>= 16; - count -= 16; - break; - case 2: - count -= 32; - break; - } - } - else - count--; - - switch (mach64->accel.source_mix) - { - case MONO_SRC_HOST: - if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) - { - mix = cpu_dat & 1; - cpu_dat >>= 1; - } - else - { - mix = cpu_dat >> 31; - cpu_dat <<= 1; - } - break; - case MONO_SRC_PAT: - mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; - break; - case MONO_SRC_1: - mix = 1; - break; - case MONO_SRC_BLITSRC: - if (mach64->src_cntl & SRC_LINEAR_EN) - { - READ(mach64->accel.src_offset + src_x, mix, WIDTH_1BIT); - } - else - { - READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, mix, WIDTH_1BIT); - } - break; - } - - if (dst_x >= mach64->accel.sc_left && dst_x <= mach64->accel.sc_right && - dst_y >= mach64->accel.sc_top && dst_y <= mach64->accel.sc_bottom) - { - switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) - { - case SRC_HOST: - src_dat = host_dat; - break; - case SRC_BLITSRC: - READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, src_dat, mach64->accel.src_size); - break; - case SRC_FG: - src_dat = mach64->accel.dp_frgd_clr; - break; - case SRC_BG: - src_dat = mach64->accel.dp_bkgd_clr; - break; - default: - src_dat = 0; - break; - } - if (mach64->dst_cntl & DST_POLYGON_EN) - { - int poly_src; - READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, poly_src, mach64->accel.src_size); - if (poly_src) - mach64->accel.poly_draw = !mach64->accel.poly_draw; - } - if (!(mach64->dst_cntl & DST_POLYGON_EN) || mach64->accel.poly_draw) - { - READ(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, dest_dat, mach64->accel.dst_size); - - switch (mach64->accel.clr_cmp_fn) - { - case 1: /*TRUE*/ - cmp_clr = 1; - break; - case 4: /*DST_CLR != CLR_CMP_CLR*/ - cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr; - break; - case 5: /*DST_CLR == CLR_CMP_CLR*/ - cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; - break; - } - - if (!cmp_clr) - MIX - - WRITE(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, mach64->accel.dst_size); - } - } - - if (mach64->dst_cntl & DST_24_ROT_EN) - { - mach64->accel.dp_frgd_clr = ((mach64->accel.dp_frgd_clr >> 8) & 0xffff) | (mach64->accel.dp_frgd_clr << 16); - mach64->accel.dp_bkgd_clr = ((mach64->accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64->accel.dp_bkgd_clr << 16); - } - - mach64->accel.src_x += mach64->accel.xinc; - mach64->accel.dst_x += mach64->accel.xinc; - if (!(mach64->src_cntl & SRC_LINEAR_EN)) - { - mach64->accel.src_x_count--; - if (mach64->accel.src_x_count <= 0) - { - mach64->accel.src_x = 0; - if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) - { - mach64->accel.src_x_start = (mach64->src_y_x_start >> 16) & 0xfff; - mach64->accel.src_x_count = mach64->accel.src_width2; - } - else - mach64->accel.src_x_count = mach64->accel.src_width1; - } - } - - mach64->accel.x_count--; - - if (mach64->accel.x_count <= 0) - { - mach64->accel.x_count = mach64->accel.dst_width; - mach64->accel.dst_x = 0; - mach64->accel.dst_y += mach64->accel.yinc; - mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; - mach64->accel.src_x_count = mach64->accel.src_width1; - - if (!(mach64->src_cntl & SRC_LINEAR_EN)) - { - mach64->accel.src_x = 0; - mach64->accel.src_y += mach64->accel.yinc; - mach64->accel.src_y_count--; - if (mach64->accel.src_y_count <= 0) - { - mach64->accel.src_y = 0; - if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) - { - mach64->accel.src_y_start = mach64->src_y_x_start & 0xfff; - mach64->accel.src_y_count = mach64->accel.src_height2; - } - else - mach64->accel.src_y_count = mach64->accel.src_height1; - } - } - - mach64->accel.poly_draw = 0; - - mach64->accel.dst_height--; - - if (mach64->accel.dst_height <= 0) - { - /*Blit finished*/ - mach64_log("mach64 blit finished\n"); - mach64->accel.busy = 0; - if (mach64->dst_cntl & DST_X_TILE) - mach64->dst_y_x = (mach64->dst_y_x & 0xfff) | ((mach64->dst_y_x + (mach64->accel.dst_width << 16)) & 0xfff0000); - if (mach64->dst_cntl & DST_Y_TILE) - mach64->dst_y_x = (mach64->dst_y_x & 0xfff0000) | ((mach64->dst_y_x + (mach64->dst_height_width & 0x1fff)) & 0xfff); - return; - } - if (mach64->host_cntl & HOST_BYTE_ALIGN) - { - if (mach64->accel.source_mix == MONO_SRC_HOST) - { - if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) - cpu_dat >>= (count & 7); - else - cpu_dat <<= (count & 7); - count &= ~7; - } - } - } - } - break; - - case OP_LINE: - while (count) - { - uint32_t src_dat = 0, dest_dat; - uint32_t host_dat = 0; - int mix = 0; - int draw_pixel = !(mach64->dst_cntl & DST_POLYGON_EN); - - if (mach64->accel.source_host) - { - host_dat = cpu_dat; - switch (mach64->accel.src_size) - { - case 0: - cpu_dat >>= 8; - count -= 8; - break; - case 1: - cpu_dat >>= 16; - count -= 16; - break; - case 2: - count -= 32; - break; - } - } - else - count--; - - switch (mach64->accel.source_mix) - { - case MONO_SRC_HOST: - mix = cpu_dat >> 31; - cpu_dat <<= 1; - break; - case MONO_SRC_PAT: - mix = mach64->accel.pattern[mach64->accel.dst_y & 7][mach64->accel.dst_x & 7]; - break; - case MONO_SRC_1: - default: - mix = 1; - break; - } - - if (mach64->dst_cntl & DST_POLYGON_EN) - { - if (mach64->dst_cntl & DST_Y_MAJOR) - draw_pixel = 1; - else if ((mach64->dst_cntl & DST_X_DIR) && mach64->accel.err < (mach64->dst_bres_dec + mach64->dst_bres_inc)) /*X+*/ - draw_pixel = 1; - else if (!(mach64->dst_cntl & DST_X_DIR) && mach64->accel.err >= 0) /*X-*/ - draw_pixel = 1; - } - - if (mach64->accel.x_count == 1 && !(mach64->dst_cntl & DST_LAST_PEL)) - draw_pixel = 0; - - if (mach64->accel.dst_x >= mach64->accel.sc_left && mach64->accel.dst_x <= mach64->accel.sc_right && - mach64->accel.dst_y >= mach64->accel.sc_top && mach64->accel.dst_y <= mach64->accel.sc_bottom && draw_pixel) - { - switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) - { - case SRC_HOST: - src_dat = host_dat; - break; - case SRC_BLITSRC: - READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, src_dat, mach64->accel.src_size); - break; - case SRC_FG: - src_dat = mach64->accel.dp_frgd_clr; - break; - case SRC_BG: - src_dat = mach64->accel.dp_bkgd_clr; - break; - default: - src_dat = 0; - break; - } - - READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size); - - switch (mach64->accel.clr_cmp_fn) - { - case 1: /*TRUE*/ - cmp_clr = 1; - break; - case 4: /*DST_CLR != CLR_CMP_CLR*/ - cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr; - break; - case 5: /*DST_CLR == CLR_CMP_CLR*/ - cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; - break; - } - - if (!cmp_clr) - MIX - - WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size); - } - - mach64->accel.x_count--; - if (mach64->accel.x_count <= 0) - { - /*Blit finished*/ - mach64_log("mach64 blit finished\n"); - mach64->accel.busy = 0; - return; - } - - switch (mach64->dst_cntl & 7) - { - case 0: case 2: - mach64->accel.src_x--; - mach64->accel.dst_x--; - break; - case 1: case 3: - mach64->accel.src_x++; - mach64->accel.dst_x++; - break; - case 4: case 5: - mach64->accel.src_y--; - mach64->accel.dst_y--; - break; - case 6: case 7: - mach64->accel.src_y++; - mach64->accel.dst_y++; - break; - } - mach64_log("x %i y %i err %i inc %i dec %i\n", mach64->accel.dst_x, mach64->accel.dst_y, mach64->accel.err, mach64->dst_bres_inc, mach64->dst_bres_dec); - if (mach64->accel.err >= 0) - { - mach64->accel.err += mach64->dst_bres_dec; - - switch (mach64->dst_cntl & 7) - { - case 0: case 1: - mach64->accel.src_y--; - mach64->accel.dst_y--; - break; - case 2: case 3: - mach64->accel.src_y++; - mach64->accel.dst_y++; - break; - case 4: case 6: - mach64->accel.src_x--; - mach64->accel.dst_x--; - break; - case 5: case 7: - mach64->accel.src_x++; - mach64->accel.dst_x++; - break; - } - } - else - mach64->accel.err += mach64->dst_bres_inc; - } - break; - } -} - -void mach64_load_context(mach64_t *mach64) -{ - svga_t *svga = &mach64->svga; - uint32_t addr; - - while (mach64->context_load_cntl & 0x30000) - { - addr = ((0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256) & mach64->vram_mask; - mach64->context_mask = *(uint32_t *)&svga->vram[addr]; - mach64_log("mach64_load_context %08X from %08X : mask %08X\n", mach64->context_load_cntl, addr, mach64->context_mask); - - if (mach64->context_mask & (1 << 2)) - mach64_accel_write_fifo_l(mach64, 0x100, *(uint32_t *)&svga->vram[addr + 0x08]); - if (mach64->context_mask & (1 << 3)) - mach64_accel_write_fifo_l(mach64, 0x10c, *(uint32_t *)&svga->vram[addr + 0x0c]); - if (mach64->context_mask & (1 << 4)) - mach64_accel_write_fifo_l(mach64, 0x118, *(uint32_t *)&svga->vram[addr + 0x10]); - if (mach64->context_mask & (1 << 5)) - mach64_accel_write_fifo_l(mach64, 0x124, *(uint32_t *)&svga->vram[addr + 0x14]); - if (mach64->context_mask & (1 << 6)) - mach64_accel_write_fifo_l(mach64, 0x128, *(uint32_t *)&svga->vram[addr + 0x18]); - if (mach64->context_mask & (1 << 7)) - mach64_accel_write_fifo_l(mach64, 0x12c, *(uint32_t *)&svga->vram[addr + 0x1c]); - if (mach64->context_mask & (1 << 8)) - mach64_accel_write_fifo_l(mach64, 0x180, *(uint32_t *)&svga->vram[addr + 0x20]); - if (mach64->context_mask & (1 << 9)) - mach64_accel_write_fifo_l(mach64, 0x18c, *(uint32_t *)&svga->vram[addr + 0x24]); - if (mach64->context_mask & (1 << 10)) - mach64_accel_write_fifo_l(mach64, 0x198, *(uint32_t *)&svga->vram[addr + 0x28]); - if (mach64->context_mask & (1 << 11)) - mach64_accel_write_fifo_l(mach64, 0x1a4, *(uint32_t *)&svga->vram[addr + 0x2c]); - if (mach64->context_mask & (1 << 12)) - mach64_accel_write_fifo_l(mach64, 0x1b0, *(uint32_t *)&svga->vram[addr + 0x30]); - if (mach64->context_mask & (1 << 13)) - mach64_accel_write_fifo_l(mach64, 0x280, *(uint32_t *)&svga->vram[addr + 0x34]); - if (mach64->context_mask & (1 << 14)) - mach64_accel_write_fifo_l(mach64, 0x284, *(uint32_t *)&svga->vram[addr + 0x38]); - if (mach64->context_mask & (1 << 15)) - mach64_accel_write_fifo_l(mach64, 0x2a8, *(uint32_t *)&svga->vram[addr + 0x3c]); - if (mach64->context_mask & (1 << 16)) - mach64_accel_write_fifo_l(mach64, 0x2b4, *(uint32_t *)&svga->vram[addr + 0x40]); - if (mach64->context_mask & (1 << 17)) - mach64_accel_write_fifo_l(mach64, 0x2c0, *(uint32_t *)&svga->vram[addr + 0x44]); - if (mach64->context_mask & (1 << 18)) - mach64_accel_write_fifo_l(mach64, 0x2c4, *(uint32_t *)&svga->vram[addr + 0x48]); - if (mach64->context_mask & (1 << 19)) - mach64_accel_write_fifo_l(mach64, 0x2c8, *(uint32_t *)&svga->vram[addr + 0x4c]); - if (mach64->context_mask & (1 << 20)) - mach64_accel_write_fifo_l(mach64, 0x2cc, *(uint32_t *)&svga->vram[addr + 0x50]); - if (mach64->context_mask & (1 << 21)) - mach64_accel_write_fifo_l(mach64, 0x2d0, *(uint32_t *)&svga->vram[addr + 0x54]); - if (mach64->context_mask & (1 << 22)) - mach64_accel_write_fifo_l(mach64, 0x2d4, *(uint32_t *)&svga->vram[addr + 0x58]); - if (mach64->context_mask & (1 << 23)) - mach64_accel_write_fifo_l(mach64, 0x2d8, *(uint32_t *)&svga->vram[addr + 0x5c]); - if (mach64->context_mask & (1 << 24)) - mach64_accel_write_fifo_l(mach64, 0x300, *(uint32_t *)&svga->vram[addr + 0x60]); - if (mach64->context_mask & (1 << 25)) - mach64_accel_write_fifo_l(mach64, 0x304, *(uint32_t *)&svga->vram[addr + 0x64]); - if (mach64->context_mask & (1 << 26)) - mach64_accel_write_fifo_l(mach64, 0x308, *(uint32_t *)&svga->vram[addr + 0x68]); - if (mach64->context_mask & (1 << 27)) - mach64_accel_write_fifo_l(mach64, 0x330, *(uint32_t *)&svga->vram[addr + 0x6c]); - - mach64->context_load_cntl = *(uint32_t *)&svga->vram[addr + 0x70]; - } -} - -#define PLL_REF_DIV 0x2 -#define VCLK_POST_DIV 0x6 -#define VCLK0_FB_DIV 0x7 - -static void pll_write(mach64_t *mach64, uint32_t addr, uint8_t val) -{ - int c; - - switch (addr & 3) - { - case 0: /*Clock sel*/ - break; - case 1: /*Addr*/ - mach64->pll_addr = (val >> 2) & 0xf; - break; - case 2: /*Data*/ - mach64->pll_regs[mach64->pll_addr] = val; - mach64_log("pll_write %02x,%02x\n", mach64->pll_addr, val); - - for (c = 0; c < 4; c++) - { - double m = (double)mach64->pll_regs[PLL_REF_DIV]; - double n = (double)mach64->pll_regs[VCLK0_FB_DIV+c]; - double r = 14318184.0; - double p = (double)(1 << ((mach64->pll_regs[VCLK_POST_DIV] >> (c*2)) & 3)); - - mach64_log("PLLfreq %i = %g %g m=%02x n=%02x p=%02x\n", c, (2.0 * r * n) / (m * p), p, mach64->pll_regs[PLL_REF_DIV], mach64->pll_regs[VCLK0_FB_DIV+c], mach64->pll_regs[VCLK_POST_DIV]); - mach64->pll_freq[c] = (2.0 * r * n) / (m * p); - mach64_log(" %g\n", mach64->pll_freq[c]); - } - break; - } -} - -#define OVERLAY_EN (1 << 30) -static void mach64_vblank_start(svga_t *svga) -{ - mach64_t *mach64 = (mach64_t *)svga->p; - int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; - - mach64->crtc_int_cntl |= 4; - mach64_update_irqs(mach64); - - svga->overlay.x = (mach64->overlay_y_x_start >> 16) & 0x7ff; - svga->overlay.y = mach64->overlay_y_x_start & 0x7ff; - - svga->overlay.xsize = ((mach64->overlay_y_x_end >> 16) & 0x7ff) - svga->overlay.x; - svga->overlay.ysize = (mach64->overlay_y_x_end & 0x7ff) - svga->overlay.y; - - svga->overlay.addr = mach64->buf_offset[0] & 0x3ffff8; - svga->overlay.pitch = mach64->buf_pitch[0] & 0xfff; - - svga->overlay.ena = (mach64->overlay_scale_cntl & OVERLAY_EN) && (overlay_cmp_mix != 1); - - mach64->overlay_v_acc = 0; - mach64->scaler_update = 1; -} - -uint8_t mach64_ext_readb(uint32_t addr, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - uint8_t ret; - if (!(addr & 0x400)) - { - mach64_log("nmach64_ext_readb: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); - switch (addr & 0x3ff) - { - case 0x00: case 0x01: case 0x02: case 0x03: - READ8(addr, mach64->overlay_y_x_start); - break; - case 0x04: case 0x05: case 0x06: case 0x07: - READ8(addr, mach64->overlay_y_x_end); - break; - case 0x08: case 0x09: case 0x0a: case 0x0b: - READ8(addr, mach64->overlay_video_key_clr); - break; - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - READ8(addr, mach64->overlay_video_key_msk); - break; - case 0x10: case 0x11: case 0x12: case 0x13: - READ8(addr, mach64->overlay_graphics_key_clr); - break; - case 0x14: case 0x15: case 0x16: case 0x17: - READ8(addr, mach64->overlay_graphics_key_msk); - break; - case 0x18: case 0x19: case 0x1a: case 0x1b: - READ8(addr, mach64->overlay_key_cntl); - break; - - case 0x20: case 0x21: case 0x22: case 0x23: - READ8(addr, mach64->overlay_scale_inc); - break; - case 0x24: case 0x25: case 0x26: case 0x27: - READ8(addr, mach64->overlay_scale_cntl); - break; - case 0x28: case 0x29: case 0x2a: case 0x2b: - READ8(addr, mach64->scaler_height_width); - break; - - case 0x4a: - ret = mach64->scaler_format; - break; - - default: - ret = 0xff; - break; - } - } - else switch (addr & 0x3ff) - { - case 0x00: case 0x01: case 0x02: case 0x03: - READ8(addr, mach64->crtc_h_total_disp); - break; - case 0x08: case 0x09: case 0x0a: case 0x0b: - READ8(addr, mach64->crtc_v_total_disp); - break; - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - READ8(addr, mach64->crtc_v_sync_strt_wid); - break; - - case 0x12: case 0x13: - READ8(addr - 2, mach64->svga.vc); - break; - - case 0x14: case 0x15: case 0x16: case 0x17: - READ8(addr, mach64->crtc_off_pitch); - break; - - case 0x18: - ret = mach64->crtc_int_cntl & ~1; - if (mach64->svga.cgastat & 8) - ret |= 1; - break; - - case 0x1c: case 0x1d: case 0x1e: case 0x1f: - READ8(addr, mach64->crtc_gen_cntl); - break; - - case 0x40: case 0x41: case 0x42: case 0x43: - READ8(addr, mach64->ovr_clr); - break; - case 0x44: case 0x45: case 0x46: case 0x47: - READ8(addr, mach64->ovr_wid_left_right); - break; - case 0x48: case 0x49: case 0x4a: case 0x4b: - READ8(addr, mach64->ovr_wid_top_bottom); - break; - - case 0x60: case 0x61: case 0x62: case 0x63: - READ8(addr, mach64->cur_clr0); - break; - case 0x64: case 0x65: case 0x66: case 0x67: - READ8(addr, mach64->cur_clr1); - break; - case 0x68: case 0x69: case 0x6a: case 0x6b: - READ8(addr, mach64->cur_offset); - break; - case 0x6c: case 0x6d: case 0x6e: case 0x6f: - READ8(addr, mach64->cur_horz_vert_posn); - break; - case 0x70: case 0x71: case 0x72: case 0x73: - READ8(addr, mach64->cur_horz_vert_off); - break; - - case 0x79: - ret = 0x30; - break; - - case 0x80: case 0x81: case 0x82: case 0x83: - READ8(addr, mach64->scratch_reg0); - break; - case 0x84: case 0x85: case 0x86: case 0x87: - READ8(addr, mach64->scratch_reg1); - break; - - case 0x90: case 0x91: case 0x92: case 0x93: - READ8(addr, mach64->clock_cntl); - break; - - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - READ8(addr, mach64->mem_cntl); - break; - - case 0xc0: case 0xc1: case 0xc2: case 0xc3: - if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga); - else - ret = ati68860_ramdac_in(addr & 3, &mach64->ramdac, &mach64->svga); - break; - case 0xc4: case 0xc5: case 0xc6: case 0xc7: - if (mach64->type == MACH64_VT2) - mach64->dac_cntl |= (4 << 24); - READ8(addr, mach64->dac_cntl); - break; - - case 0xd0: case 0xd1: case 0xd2: case 0xd3: - READ8(addr, mach64->gen_test_cntl); - break; - - case 0xdc: case 0xdd: case 0xde: case 0xdf: - if (mach64->type == MACH64_GX) - mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); - else - mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 24) << 4); - READ8(addr, mach64->config_cntl); - break; - case 0xe0: case 0xe1: case 0xe2: case 0xe3: - READ8(addr, mach64->config_chip_id); - break; - case 0xe4: case 0xe5: case 0xe6: case 0xe7: - READ8(addr, mach64->config_stat0); - break; - - case 0x100: case 0x101: case 0x102: case 0x103: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_off_pitch); - break; - case 0x104: case 0x105: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_y_x); - break; - case 0x108: case 0x109: case 0x11c: case 0x11d: - mach64_wait_fifo_idle(mach64); - READ8(addr + 2, mach64->dst_y_x); - break; - case 0x10c: case 0x10d: case 0x10e: case 0x10f: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_y_x); - break; - case 0x110: case 0x111: - addr += 2; - case 0x114: case 0x115: - case 0x118: case 0x119: case 0x11a: case 0x11b: - case 0x11e: case 0x11f: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_height_width); - break; - - case 0x120: case 0x121: case 0x122: case 0x123: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_bres_lnth); - break; - case 0x124: case 0x125: case 0x126: case 0x127: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_bres_err); - break; - case 0x128: case 0x129: case 0x12a: case 0x12b: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_bres_inc); - break; - case 0x12c: case 0x12d: case 0x12e: case 0x12f: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_bres_dec); - break; - - case 0x130: case 0x131: case 0x132: case 0x133: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_cntl); - break; - - case 0x180: case 0x181: case 0x182: case 0x183: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_off_pitch); - break; - case 0x184: case 0x185: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_y_x); - break; - case 0x188: case 0x189: - mach64_wait_fifo_idle(mach64); - READ8(addr + 2, mach64->src_y_x); - break; - case 0x18c: case 0x18d: case 0x18e: case 0x18f: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_y_x); - break; - case 0x190: case 0x191: - mach64_wait_fifo_idle(mach64); - READ8(addr + 2, mach64->src_height1_width1); - break; - case 0x194: case 0x195: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_height1_width1); - break; - case 0x198: case 0x199: case 0x19a: case 0x19b: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_height1_width1); - break; - case 0x19c: case 0x19d: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_y_x_start); - break; - case 0x1a0: case 0x1a1: - mach64_wait_fifo_idle(mach64); - READ8(addr + 2, mach64->src_y_x_start); - break; - case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_y_x_start); - break; - case 0x1a8: case 0x1a9: - mach64_wait_fifo_idle(mach64); - READ8(addr + 2, mach64->src_height2_width2); - break; - case 0x1ac: case 0x1ad: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_height2_width2); - break; - case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_height2_width2); - break; - - case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_cntl); - break; - - case 0x240: case 0x241: case 0x242: case 0x243: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->host_cntl); - break; - - case 0x280: case 0x281: case 0x282: case 0x283: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->pat_reg0); - break; - case 0x284: case 0x285: case 0x286: case 0x287: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->pat_reg1); - break; - - case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->sc_left_right); - break; - case 0x2a4: case 0x2a5: - addr += 2; - case 0x2aa: case 0x2ab: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->sc_left_right); - break; - - case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->sc_top_bottom); - break; - case 0x2b0: case 0x2b1: - addr += 2; - case 0x2b6: case 0x2b7: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->sc_top_bottom); - break; - - case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dp_bkgd_clr); - break; - case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dp_frgd_clr); - break; - - case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dp_pix_width); - break; - case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dp_mix); - break; - case 0x2d8: case 0x2d9: case 0x2da: case 0x2db: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dp_src); - break; - - case 0x300: case 0x301: case 0x302: case 0x303: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->clr_cmp_clr); - break; - case 0x304: case 0x305: case 0x306: case 0x307: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->clr_cmp_mask); - break; - case 0x308: case 0x309: case 0x30a: case 0x30b: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->clr_cmp_cntl); - break; - - case 0x310: case 0x311: - if (!FIFO_EMPTY) - wake_fifo_thread(mach64); - ret = 0; - if (FIFO_FULL) - ret = 0xff; - break; - - case 0x320: case 0x321: case 0x322: case 0x323: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->context_mask); - break; - - case 0x330: case 0x331: - mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_cntl); - break; - case 0x332: - mach64_wait_fifo_idle(mach64); - READ8(addr - 2, mach64->src_cntl); - break; - case 0x333: - mach64_wait_fifo_idle(mach64); - READ8(addr - 3, mach64->pat_cntl); - break; - - case 0x338: - ret = FIFO_EMPTY ? 0 : 1; - break; - - default: - ret = 0; - break; - } - if ((addr & 0x3fc) != 0x018) mach64_log("mach64_ext_readb : addr %08X ret %02X\n", addr, ret); - return ret; -} -uint16_t mach64_ext_readw(uint32_t addr, void *p) -{ - uint16_t ret; - if (!(addr & 0x400)) - { - mach64_log("nmach64_ext_readw: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); - ret = 0xffff; - } - else switch (addr & 0x3ff) - { - default: - ret = mach64_ext_readb(addr, p); - ret |= mach64_ext_readb(addr + 1, p) << 8; - break; - } - if ((addr & 0x3fc) != 0x018) mach64_log("mach64_ext_readw : addr %08X ret %04X\n", addr, ret); - return ret; -} -uint32_t mach64_ext_readl(uint32_t addr, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - uint32_t ret; - if (!(addr & 0x400)) - { - mach64_log("nmach64_ext_readl: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); - ret = 0xffffffff; - } - else switch (addr & 0x3ff) - { - case 0x18: - ret = mach64->crtc_int_cntl & ~1; - if (mach64->svga.cgastat & 8) - ret |= 1; - break; - - case 0xb4: - ret = (mach64->bank_w[0] >> 15) | ((mach64->bank_w[1] >> 15) << 16); - break; - case 0xb8: - ret = (mach64->bank_r[0] >> 15) | ((mach64->bank_r[1] >> 15) << 16); - break; - - default: - ret = mach64_ext_readw(addr, p); - ret |= mach64_ext_readw(addr + 2, p) << 16; - break; - } - if ((addr & 0x3fc) != 0x018) mach64_log("mach64_ext_readl : addr %08X ret %08X\n", addr, ret); - return ret; -} - -void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; - - mach64_log("mach64_ext_writeb : addr %08X val %02X %04x(%08x):%08x\n", addr, val, CS,cs,cpu_state.pc); - - if (!(addr & 0x400)) - { - switch (addr & 0x3ff) - { - case 0x00: case 0x01: case 0x02: case 0x03: - WRITE8(addr, mach64->overlay_y_x_start, val); - break; - case 0x04: case 0x05: case 0x06: case 0x07: - WRITE8(addr, mach64->overlay_y_x_end, val); - break; - case 0x08: case 0x09: case 0x0a: case 0x0b: - WRITE8(addr, mach64->overlay_video_key_clr, val); - break; - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - WRITE8(addr, mach64->overlay_video_key_msk, val); - break; - case 0x10: case 0x11: case 0x12: case 0x13: - WRITE8(addr, mach64->overlay_graphics_key_clr, val); - break; - case 0x14: case 0x15: case 0x16: case 0x17: - WRITE8(addr, mach64->overlay_graphics_key_msk, val); - break; - case 0x18: case 0x19: case 0x1a: case 0x1b: - WRITE8(addr, mach64->overlay_key_cntl, val); - break; - - case 0x20: case 0x21: case 0x22: case 0x23: - WRITE8(addr, mach64->overlay_scale_inc, val); - break; - case 0x24: case 0x25: case 0x26: case 0x27: - WRITE8(addr, mach64->overlay_scale_cntl, val); - break; - case 0x28: case 0x29: case 0x2a: case 0x2b: - WRITE8(addr, mach64->scaler_height_width, val); - break; - - case 0x4a: - mach64->scaler_format = val & 0xf; - break; - - case 0x80: case 0x81: case 0x82: case 0x83: - WRITE8(addr, mach64->buf_offset[0], val); - break; - - case 0x8c: case 0x8d: case 0x8e: case 0x8f: - WRITE8(addr, mach64->buf_pitch[0], val); - break; - - case 0x98: case 0x99: case 0x9a: case 0x9b: - WRITE8(addr, mach64->buf_offset[1], val); - break; - - case 0xa4: case 0xa5: case 0xa6: case 0xa7: - WRITE8(addr, mach64->buf_pitch[1], val); - break; - } - - mach64_log("nmach64_ext_writeb: addr=%04x val=%02x\n", addr, val); - } - else if (addr & 0x300) - { - mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE); - } - else switch (addr & 0x3ff) - { - case 0x00: case 0x01: case 0x02: case 0x03: - WRITE8(addr, mach64->crtc_h_total_disp, val); - svga_recalctimings(&mach64->svga); - break; - case 0x08: case 0x09: case 0x0a: case 0x0b: - WRITE8(addr, mach64->crtc_v_total_disp, val); - svga_recalctimings(&mach64->svga); - break; - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - WRITE8(addr, mach64->crtc_v_sync_strt_wid, val); - svga_recalctimings(&mach64->svga); - break; - - case 0x14: case 0x15: case 0x16: case 0x17: - WRITE8(addr, mach64->crtc_off_pitch, val); - svga_recalctimings(&mach64->svga); - svga->fullchange = changeframecount; - break; - - case 0x18: - mach64->crtc_int_cntl = (mach64->crtc_int_cntl & 0x75) | (val & ~0x75); - if (val & 4) - mach64->crtc_int_cntl &= ~4; - mach64_update_irqs(mach64); - break; - - case 0x1c: case 0x1d: case 0x1e: case 0x1f: - WRITE8(addr, mach64->crtc_gen_cntl, val); - if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) - svga->fb_only = 1; - else - svga->fb_only = 0; - svga_recalctimings(&mach64->svga); - break; - - case 0x40: case 0x41: case 0x42: case 0x43: - WRITE8(addr, mach64->ovr_clr, val); - break; - case 0x44: case 0x45: case 0x46: case 0x47: - WRITE8(addr, mach64->ovr_wid_left_right, val); - break; - case 0x48: case 0x49: case 0x4a: case 0x4b: - WRITE8(addr, mach64->ovr_wid_top_bottom, val); - break; - - case 0x60: case 0x61: case 0x62: case 0x63: - WRITE8(addr, mach64->cur_clr0, val); - if (mach64->type == MACH64_VT2) - mach64->ramdac.pallook[0] = makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff); - break; - case 0x64: case 0x65: case 0x66: case 0x67: - WRITE8(addr, mach64->cur_clr1, val); - if (mach64->type == MACH64_VT2) - mach64->ramdac.pallook[1] = makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff); - break; - case 0x68: case 0x69: case 0x6a: case 0x6b: - WRITE8(addr, mach64->cur_offset, val); - svga->hwcursor.addr = (mach64->cur_offset & 0xfffff) * 8; - mach64_cursor_dump(mach64); - break; - case 0x6c: case 0x6d: case 0x6e: case 0x6f: - WRITE8(addr, mach64->cur_horz_vert_posn, val); - svga->hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff; - svga->hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff; - mach64_cursor_dump(mach64); - break; - case 0x70: case 0x71: case 0x72: case 0x73: - WRITE8(addr, mach64->cur_horz_vert_off, val); - svga->hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f; - svga->hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f; - mach64_cursor_dump(mach64); - break; - - case 0x80: case 0x81: case 0x82: case 0x83: - WRITE8(addr, mach64->scratch_reg0, val); - break; - case 0x84: case 0x85: case 0x86: case 0x87: - WRITE8(addr, mach64->scratch_reg1, val); - break; - - case 0x90: case 0x91: case 0x92: case 0x93: - WRITE8(addr, mach64->clock_cntl, val); - if (mach64->type == MACH64_GX) - ics2595_write(&mach64->ics2595, val & 0x40, val & 0xf); - else - { - pll_write(mach64, addr, val); - mach64->ics2595.output_clock = mach64->pll_freq[mach64->clock_cntl & 3]; - } - svga_recalctimings(&mach64->svga); - break; - - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - WRITE8(addr, mach64->mem_cntl, val); - break; - - case 0xb4: - mach64->bank_w[0] = val * 32768; - mach64_log("mach64 : write bank A0000-A7FFF set to %08X\n", mach64->bank_w[0]); - break; - case 0xb5: case 0xb6: - mach64->bank_w[1] = val * 32768; - mach64_log("mach64 : write bank A8000-AFFFF set to %08X\n", mach64->bank_w[1]); - break; - case 0xb8: - mach64->bank_r[0] = val * 32768; - mach64_log("mach64 : read bank A0000-A7FFF set to %08X\n", mach64->bank_r[0]); - break; - case 0xb9: case 0xba: - mach64->bank_r[1] = val * 32768; - mach64_log("mach64 : read bank A8000-AFFFF set to %08X\n", mach64->bank_r[1]); - break; - - case 0xc0: case 0xc1: case 0xc2: case 0xc3: - if (mach64->type == MACH64_GX) - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga); - else - ati68860_ramdac_out(addr & 3, val, &mach64->ramdac, &mach64->svga); - break; - case 0xc4: case 0xc5: case 0xc6: case 0xc7: - WRITE8(addr, mach64->dac_cntl, val); - svga_set_ramdac_type(svga, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); - ati68860_set_ramdac_type(&mach64->ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); - break; - - case 0xd0: case 0xd1: case 0xd2: case 0xd3: - WRITE8(addr, mach64->gen_test_cntl, val); - ati_eeprom_write(&mach64->eeprom, mach64->gen_test_cntl & 0x10, mach64->gen_test_cntl & 2, mach64->gen_test_cntl & 1); - mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0); - svga->hwcursor.ena = mach64->gen_test_cntl & 0x80; - mach64_cursor_dump(mach64); - break; - - case 0xdc: case 0xdd: case 0xde: case 0xdf: - WRITE8(addr, mach64->config_cntl, val); - mach64_updatemapping(mach64); - break; - - case 0xe4: case 0xe5: case 0xe6: case 0xe7: - if (mach64->type != MACH64_GX) - WRITE8(addr, mach64->config_stat0, val); - break; - } -} -void mach64_ext_writew(uint32_t addr, uint16_t val, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - mach64_log("mach64_ext_writew : addr %08X val %04X\n", addr, val); - if (!(addr & 0x400)) - { - mach64_log("nmach64_ext_writew: addr=%04x val=%04x %04x(%08x):%08x\n", addr, val, CS, cs, cpu_state.pc); - - mach64_ext_writeb(addr, val, p); - mach64_ext_writeb(addr + 1, val >> 8, p); - } - else if (addr & 0x300) - { - mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD); - } - else switch (addr & 0x3fe) - { - default: - mach64_ext_writeb(addr, val, p); - mach64_ext_writeb(addr + 1, val >> 8, p); - break; - } -} -void mach64_ext_writel(uint32_t addr, uint32_t val, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - if ((addr & 0x3c0) != 0x200) - mach64_log("mach64_ext_writel : addr %08X val %08X\n", addr, val); - if (!(addr & 0x400)) - { - mach64_log("nmach64_ext_writel: addr=%04x val=%08x %04x(%08x):%08x\n", addr, val, CS, cs, cpu_state.pc); - - mach64_ext_writew(addr, val, p); - mach64_ext_writew(addr + 2, val >> 16, p); - } - else if (addr & 0x300) - { - mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD); - } - else switch (addr & 0x3fc) - { - default: - mach64_ext_writew(addr, val, p); - mach64_ext_writew(addr + 2, val >> 16, p); - break; - } -} - -uint8_t mach64_ext_inb(uint16_t port, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - uint8_t ret; - switch (port) - { - case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef: - case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef: - ret = mach64_ext_readb(0x400 | 0x00 | (port & 3), p); - break; - case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef: - ret = mach64_ext_readb(0x400 | 0x08 | (port & 3), p); - break; - case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef: - ret = mach64_ext_readb(0x400 | 0x0c | (port & 3), p); - break; - - case 0x12ec: case 0x12ed: case 0x12ee: case 0x12ef: - ret = mach64_ext_readb(0x400 | 0x10 | (port & 3), p); - break; - - case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef: - ret = mach64_ext_readb(0x400 | 0x14 | (port & 3), p); - break; - - case 0x1aec: - ret = mach64_ext_readb(0x400 | 0x18, p); - break; - - case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef: - ret = mach64_ext_readb(0x400 | 0x1c | (port & 3), p); - break; - - case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef: - ret = mach64_ext_readb(0x400 | 0x40 | (port & 3), p); - break; - case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef: - ret = mach64_ext_readb(0x400 | 0x44 | (port & 3), p); - break; - case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef: - ret = mach64_ext_readb(0x400 | 0x48 | (port & 3), p); - break; - case 0x2eec: case 0x2eed: case 0x2eee: case 0x2eef: - ret = mach64_ext_readb(0x400 | 0x60 | (port & 3), p); - break; - - case 0x32ec: case 0x32ed: case 0x32ee: case 0x32ef: - ret = mach64_ext_readb(0x400 | 0x64 | (port & 3), p); - break; - case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef: - ret = mach64_ext_readb(0x400 | 0x68 | (port & 3), p); - break; - case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef: - ret = mach64_ext_readb(0x400 | 0x6c | (port & 3), p); - break; - case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef: - ret = mach64_ext_readb(0x400 | 0x70 | (port & 3), p); - break; - - case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef: - ret = mach64_ext_readb(0x400 | 0x80 | (port & 3), p); - break; - case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef: - ret = mach64_ext_readb(0x400 | 0x84 | (port & 3), p); - break; - case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef: - ret = mach64_ext_readb(0x400 | 0x90 | (port & 3), p); - break; - - case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef: - ret = mach64_ext_readb(0x400 | 0xb0 | (port & 3), p); - break; - - case 0x56ec: - ret = mach64_ext_readb(0x400 | 0xb4, p); - break; - case 0x56ed: case 0x56ee: - ret = mach64_ext_readb(0x400 | 0xb5, p); - break; - case 0x5aec: - ret = mach64_ext_readb(0x400 | 0xb8, p); - break; - case 0x5aed: case 0x5aee: - ret = mach64_ext_readb(0x400 | 0xb9, p); - break; - - case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: - if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga); - else - ret = ati68860_ramdac_in(port & 3, &mach64->ramdac, &mach64->svga); - break; - - case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: - ret = mach64_ext_readb(0x400 | 0xc4 | (port & 3), p); - break; - - case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef: - ret = mach64_ext_readb(0x400 | 0xd0 | (port & 3), p); - break; - - case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: - mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); - READ8(port, mach64->config_cntl); - break; - - case 0x6eec: case 0x6eed: case 0x6eee: case 0x6eef: - ret = mach64_ext_readb(0x400 | 0xe0 | (port & 3), p); - break; - - case 0x72ec: case 0x72ed: case 0x72ee: case 0x72ef: - ret = mach64_ext_readb(0x400 | 0xe4 | (port & 3), p); - break; - - default: - ret = 0; - break; - } - mach64_log("mach64_ext_inb : port %04X ret %02X %04X:%04X\n", port, ret, CS,cpu_state.pc); - return ret; -} -uint16_t mach64_ext_inw(uint16_t port, void *p) -{ - uint16_t ret; - switch (port) - { - default: - ret = mach64_ext_inb(port, p); - ret |= (mach64_ext_inb(port + 1, p) << 8); - break; - } - mach64_log("mach64_ext_inw : port %04X ret %04X\n", port, ret); - return ret; -} -uint32_t mach64_ext_inl(uint16_t port, void *p) -{ - uint32_t ret; - switch (port) - { - case 0x56ec: - ret = mach64_ext_readl(0x400 | 0xb4, p); - break; - case 0x5aec: - ret = mach64_ext_readl(0x400 | 0xb8, p); - break; - - default: - ret = mach64_ext_inw(port, p); - ret |= (mach64_ext_inw(port + 2, p) << 16); - break; - } - mach64_log("mach64_ext_inl : port %04X ret %08X\n", port, ret); - return ret; -} - -void mach64_ext_outb(uint16_t port, uint8_t val, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - mach64_log("mach64_ext_outb : port %04X val %02X %04X:%04X\n", port, val, CS,cpu_state.pc); - switch (port) - { - case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef: - case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef: - mach64_ext_writeb(0x400 | 0x00 | (port & 3), val, p); - break; - case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef: - mach64_ext_writeb(0x400 | 0x08 | (port & 3), val, p); - break; - case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef: - mach64_ext_writeb(0x400 | 0x0c | (port & 3), val, p); - break; - - case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef: - mach64_ext_writeb(0x400 | 0x14 | (port & 3), val, p); - break; - - case 0x1aec: - mach64_ext_writeb(0x400 | 0x18, val, p); - break; - - case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef: - mach64_ext_writeb(0x400 | 0x1c | (port & 3), val, p); - break; - - case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef: - mach64_ext_writeb(0x400 | 0x40 | (port & 3), val, p); - break; - case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef: - mach64_ext_writeb(0x400 | 0x44 | (port & 3), val, p); - break; - case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef: - mach64_ext_writeb(0x400 | 0x48 | (port & 3), val, p); - break; - case 0x2eec: case 0x2eed: case 0x2eee: case 0x2eef: - mach64_ext_writeb(0x400 | 0x60 | (port & 3), val, p); - break; - - case 0x32ec: case 0x32ed: case 0x32ee: case 0x32ef: - mach64_ext_writeb(0x400 | 0x64 | (port & 3), val, p); - break; - case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef: - mach64_ext_writeb(0x400 | 0x68 | (port & 3), val, p); - break; - case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef: - mach64_ext_writeb(0x400 | 0x6c | (port & 3), val, p); - break; - case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef: - mach64_ext_writeb(0x400 | 0x70 | (port & 3), val, p); - break; - - case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef: - mach64_ext_writeb(0x400 | 0x80 | (port & 3), val, p); - break; - case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef: - mach64_ext_writeb(0x400 | 0x84 | (port & 3), val, p); - break; - case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef: - mach64_ext_writeb(0x400 | 0x90 | (port & 3), val, p); - break; - - case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef: - mach64_ext_writeb(0x400 | 0xb0 | (port & 3), val, p); - break; - - case 0x56ec: - mach64_ext_writeb(0x400 | 0xb4, val, p); - break; - case 0x56ed: case 0x56ee: - mach64_ext_writeb(0x400 | 0xb5, val, p); - break; - case 0x5aec: - mach64_ext_writeb(0x400 | 0xb8, val, p); - break; - case 0x5aed: case 0x5aee: - mach64_ext_writeb(0x400 | 0xb9, val, p); - break; - - case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: - if (mach64->type == MACH64_GX) - ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga); - else - ati68860_ramdac_out(port & 3, val, &mach64->ramdac, &mach64->svga); - break; - - case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: - mach64_ext_writeb(0x400 | 0xc4 | (port & 3), val, p); - break; - - case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef: - mach64_ext_writeb(0x400 | 0xd0 | (port & 3), val, p); - break; - - case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: - WRITE8(port, mach64->config_cntl, val); - mach64_updatemapping(mach64); - break; - } -} -void mach64_ext_outw(uint16_t port, uint16_t val, void *p) -{ - mach64_log("mach64_ext_outw : port %04X val %04X\n", port, val); - switch (port) - { - default: - mach64_ext_outb(port, val, p); - mach64_ext_outb(port + 1, val >> 8, p); - break; - } -} -void mach64_ext_outl(uint16_t port, uint32_t val, void *p) -{ - mach64_log("mach64_ext_outl : port %04X val %08X\n", port, val); - switch (port) - { - default: - mach64_ext_outw(port, val, p); - mach64_ext_outw(port + 2, val >> 16, p); - break; - } -} - -static uint8_t mach64_block_inb(uint16_t port, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - uint8_t ret; - - ret = mach64_ext_readb(0x400 | (port & 0x3ff), mach64); - mach64_log("mach64_block_inb : port %04X ret %02X %04x:%04x\n", port, ret, CS,cpu_state.pc); - return ret; -} -static uint16_t mach64_block_inw(uint16_t port, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - uint16_t ret; - - ret = mach64_ext_readw(0x400 | (port & 0x3ff), mach64); - mach64_log("mach64_block_inw : port %04X ret %04X\n", port, ret); - return ret; -} -static uint32_t mach64_block_inl(uint16_t port, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - uint32_t ret; - - ret = mach64_ext_readl(0x400 | (port & 0x3ff), mach64); - mach64_log("mach64_block_inl : port %04X ret %08X\n", port, ret); - return ret; -} - -static void mach64_block_outb(uint16_t port, uint8_t val, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - - mach64_log("mach64_block_outb : port %04X val %02X\n ", port, val); - mach64_ext_writeb(0x400 | (port & 0x3ff), val, mach64); -} -static void mach64_block_outw(uint16_t port, uint16_t val, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - - mach64_log("mach64_block_outw : port %04X val %04X\n ", port, val); - mach64_ext_writew(0x400 | (port & 0x3ff), val, mach64); -} -static void mach64_block_outl(uint16_t port, uint32_t val, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - - mach64_log("mach64_block_outl : port %04X val %08X\n ", port, val); - mach64_ext_writel(0x400 | (port & 0x3ff), val, mach64); -} - -void mach64_write(uint32_t addr, uint8_t val, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; - addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; - svga_write_linear(addr, val, svga); -} -void mach64_writew(uint32_t addr, uint16_t val, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; - - addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; - svga_writew_linear(addr, val, svga); -} -void mach64_writel(uint32_t addr, uint32_t val, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; - - addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; - svga_writel_linear(addr, val, svga); -} - -uint8_t mach64_read(uint32_t addr, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; - uint8_t ret; - addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; - ret = svga_read_linear(addr, svga); - return ret; -} -uint16_t mach64_readw(uint32_t addr, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; - - addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; - return svga_readw_linear(addr, svga); -} -uint32_t mach64_readl(uint32_t addr, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; - - addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; - return svga_readl_linear(addr, svga); -} - -void mach64_hwcursor_draw(svga_t *svga, int displine) -{ - mach64_t *mach64 = (mach64_t *)svga->p; - int x, offset; - uint8_t dat; - uint32_t col0 = mach64->ramdac.pallook[0]; - uint32_t col1 = mach64->ramdac.pallook[1]; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - - offset = svga->hwcursor_latch.xoff; - for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) - { - dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 32 + x_add] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 32 + x_add] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 33 + x_add] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 33 + x_add] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 34 + x_add] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 34 + x_add] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 35 + x_add] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 35 + x_add] ^= 0xFFFFFF; - dat >>= 2; - offset += 4; - } - svga->hwcursor_latch.addr += 16; -} - -#define CLAMP(x) do \ - { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } \ - while (0) - -#define DECODE_ARGB1555() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) \ - { \ - uint16_t dat = ((uint16_t *)src)[x]; \ - \ - int b = dat & 0x1f; \ - int g = (dat >> 5) & 0x1f; \ - int r = (dat >> 10) & 0x1f; \ - \ - b = (b << 3) | (b >> 2); \ - g = (g << 3) | (g >> 2); \ - r = (r << 3) | (r >> 2); \ - \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - } \ - } while (0) - -#define DECODE_RGB565() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) \ - { \ - uint16_t dat = ((uint16_t *)src)[x]; \ - \ - int b = dat & 0x1f; \ - int g = (dat >> 5) & 0x3f; \ - int r = (dat >> 11) & 0x1f; \ - \ - b = (b << 3) | (b >> 2); \ - g = (g << 2) | (g >> 4); \ - r = (r << 3) | (r >> 2); \ - \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - } \ - } while (0) - -#define DECODE_ARGB8888() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) \ - { \ - int b = src[0]; \ - int g = src[1]; \ - int r = src[2]; \ - src += 4; \ - \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - } \ - } while (0) - -#define DECODE_VYUY422() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x += 2) \ - { \ - uint8_t y1, y2; \ - int8_t u, v; \ - int dR, dG, dB; \ - int r, g, b; \ - \ - y1 = src[0]; \ - u = src[1] - 0x80; \ - y2 = src[2]; \ - v = src[3] - 0x80; \ - src += 4; \ - \ - dR = (359*v) >> 8; \ - dG = (88*u + 183*v) >> 8; \ - dB = (453*u) >> 8; \ - \ - r = y1 + dR; \ - CLAMP(r); \ - g = y1 - dG; \ - CLAMP(g); \ - b = y1 + dB; \ - CLAMP(b); \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - \ - r = y2 + dR; \ - CLAMP(r); \ - g = y2 - dG; \ - CLAMP(g); \ - b = y2 + dB; \ - CLAMP(b); \ - mach64->overlay_dat[x+1] = (r << 16) | (g << 8) | b; \ - } \ - } while (0) - -#define DECODE_YVYU422() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x += 2) \ - { \ - uint8_t y1, y2; \ - int8_t u, v; \ - int dR, dG, dB; \ - int r, g, b; \ - \ - u = src[0] - 0x80; \ - y1 = src[1]; \ - v = src[2] - 0x80; \ - y2 = src[3]; \ - src += 4; \ - \ - dR = (359*v) >> 8; \ - dG = (88*u + 183*v) >> 8; \ - dB = (453*u) >> 8; \ - \ - r = y1 + dR; \ - CLAMP(r); \ - g = y1 - dG; \ - CLAMP(g); \ - b = y1 + dB; \ - CLAMP(b); \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - \ - r = y2 + dR; \ - CLAMP(r); \ - g = y2 - dG; \ - CLAMP(g); \ - b = y2 + dB; \ - CLAMP(b); \ - mach64->overlay_dat[x+1] = (r << 16) | (g << 8) | b; \ - } \ - } while (0) - -void mach64_overlay_draw(svga_t *svga, int displine) -{ - mach64_t *mach64 = (mach64_t *)svga->p; - int x; - int h_acc = 0; - int h_max = (mach64->scaler_height_width >> 16) & 0x3ff; - int h_inc = mach64->overlay_scale_inc >> 16; - int v_max = mach64->scaler_height_width & 0x3ff; - int v_inc = mach64->overlay_scale_inc & 0xffff; - uint32_t *p; - uint8_t *src = &svga->vram[svga->overlay.addr]; - int old_y = mach64->overlay_v_acc; - int y_diff; - int video_key_fn = mach64->overlay_key_cntl & 5; - int graphics_key_fn = (mach64->overlay_key_cntl >> 4) & 5; - int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; - - p = &((uint32_t *)buffer32->line[displine])[32 + mach64->svga.overlay_latch.x]; - - if (mach64->scaler_update) - { - switch (mach64->scaler_format) - { - case 0x3: - DECODE_ARGB1555(); - break; - case 0x4: - DECODE_RGB565(); - break; - case 0x6: - DECODE_ARGB8888(); - break; - case 0xb: - DECODE_VYUY422(); - break; - case 0xc: - DECODE_YVYU422(); - break; - - default: - mach64_log("Unknown Mach64 scaler format %x\n", mach64->scaler_format); - /*Fill buffer with something recognisably wrong*/ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) - mach64->overlay_dat[x] = 0xff00ff; - break; - } - } - - if (overlay_cmp_mix == 2) - { - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) - { - int h = h_acc >> 12; - - p[x] = mach64->overlay_dat[h]; - - h_acc += h_inc; - if (h_acc > (h_max << 12)) - h_acc = (h_max << 12); - } - } - else - { - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) - { - int h = h_acc >> 12; - int gr_cmp = 0, vid_cmp = 0; - int use_video = 0; - - switch (video_key_fn) - { - case 0: vid_cmp = 0; break; - case 1: vid_cmp = 1; break; - case 4: vid_cmp = ((mach64->overlay_dat[h] ^ mach64->overlay_video_key_clr) & mach64->overlay_video_key_msk); break; - case 5: vid_cmp = !((mach64->overlay_dat[h] ^ mach64->overlay_video_key_clr) & mach64->overlay_video_key_msk); break; - } - switch (graphics_key_fn) - { - case 0: gr_cmp = 0; break; - case 1: gr_cmp = 1; break; - case 4: gr_cmp = (((p[x]) ^ mach64->overlay_graphics_key_clr) & mach64->overlay_graphics_key_msk & 0xffffff); break; - case 5: gr_cmp = !(((p[x]) ^ mach64->overlay_graphics_key_clr) & mach64->overlay_graphics_key_msk & 0xffffff); break; - } - vid_cmp = vid_cmp ? -1 : 0; - gr_cmp = gr_cmp ? -1 : 0; - - switch (overlay_cmp_mix) - { - case 0x0: use_video = gr_cmp; break; - case 0x1: use_video = 0; break; - case 0x2: use_video = ~0; break; - case 0x3: use_video = ~gr_cmp; break; - case 0x4: use_video = ~vid_cmp; break; - case 0x5: use_video = gr_cmp ^ vid_cmp; break; - case 0x6: use_video = ~gr_cmp ^ vid_cmp; break; - case 0x7: use_video = vid_cmp; break; - case 0x8: use_video = ~gr_cmp | ~vid_cmp; break; - case 0x9: use_video = gr_cmp | ~vid_cmp; break; - case 0xa: use_video = ~gr_cmp | vid_cmp; break; - case 0xb: use_video = gr_cmp | vid_cmp; break; - case 0xc: use_video = gr_cmp & vid_cmp; break; - case 0xd: use_video = ~gr_cmp & vid_cmp; break; - case 0xe: use_video = gr_cmp & ~vid_cmp; break; - case 0xf: use_video = ~gr_cmp & ~vid_cmp; break; - } - - if (use_video) - p[x] = mach64->overlay_dat[h]; - - h_acc += h_inc; - if (h_acc > (h_max << 12)) - h_acc = (h_max << 12); - } - } - - mach64->overlay_v_acc += v_inc; - if (mach64->overlay_v_acc > (v_max << 12)) - mach64->overlay_v_acc = v_max << 12; - - y_diff = (mach64->overlay_v_acc >> 12) - (old_y >> 12); - - if (mach64->scaler_format == 6) - svga->overlay.addr += svga->overlay.pitch*4*y_diff; - else - svga->overlay.addr += svga->overlay.pitch*2*y_diff; - - mach64->scaler_update = y_diff; -} - -static void mach64_io_remove(mach64_t *mach64) -{ - int c; - uint16_t io_base = 0x02ec; - - switch (mach64->io_base) - { - case 0: - default: - io_base = 0x02ec; - break; - case 1: - io_base = 0x01cc; - break; - case 2: - io_base = 0x01c8; - break; - case 3: - fatal("Attempting to use the reserved value for I/O Base\n"); - return; - } - - io_removehandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - - for (c = 0; c < 8; c++) - { - io_removehandler((c * 0x1000) + 0x0000 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_removehandler((c * 0x1000) + 0x0400 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_removehandler((c * 0x1000) + 0x0800 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_removehandler((c * 0x1000) + 0x0c00 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - } - - io_removehandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - - if (mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) - io_removehandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); -} - -static void mach64_io_set(mach64_t *mach64) -{ - int c; - - mach64_io_remove(mach64); - - io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - - if (!mach64->use_block_decoded_io) - { - for (c = 0; c < 8; c++) - { - io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - } - } - - io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - - if (mach64->use_block_decoded_io && mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) - io_sethandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); -} - -uint8_t mach64_pci_read(int func, int addr, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - - switch (addr) - { - case 0x00: return 0x02; /*ATi*/ - case 0x01: return 0x10; - - case 0x02: return mach64->pci_id & 0xff; - case 0x03: return mach64->pci_id >> 8; - - case PCI_REG_COMMAND: - return mach64->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - - case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ - - case 0x08: /*Revision ID*/ - if (mach64->type == MACH64_GX) - return 0; - return 0x40; - - case 0x09: return 0; /*Programming interface*/ - - case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/ - case 0x0b: return 0x03; - - case 0x10: return 0x00; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: return mach64->linear_base >> 16; - case 0x13: return mach64->linear_base >> 24; - - case 0x14: - if (mach64->type == MACH64_VT2) - return 0x01; /*Block decoded IO address*/ - return 0x00; - case 0x15: - if (mach64->type == MACH64_VT2) - return mach64->block_decoded_io >> 8; - return 0x00; - case 0x16: - if (mach64->type == MACH64_VT2) - return mach64->block_decoded_io >> 16; - return 0x00; - case 0x17: - if (mach64->type == MACH64_VT2) - return mach64->block_decoded_io >> 24; - return 0x00; - - case 0x30: return mach64->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return mach64->pci_regs[0x32]; - case 0x33: return mach64->pci_regs[0x33]; - - case 0x3c: return mach64->int_line; - case 0x3d: return PCI_INTA; - - case 0x40: return mach64->use_block_decoded_io | mach64->io_base; - } - return 0; -} - -void mach64_pci_write(int func, int addr, uint8_t val, void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - - switch (addr) - { - case PCI_REG_COMMAND: - mach64->pci_regs[PCI_REG_COMMAND] = val & 0x27; - if (val & PCI_COMMAND_IO) - mach64_io_set(mach64); - else - mach64_io_remove(mach64); - mach64_updatemapping(mach64); - break; - - case 0x12: - if (mach64->type == MACH64_VT2) - val = 0; - mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16); - mach64_updatemapping(mach64); - break; - case 0x13: - mach64->linear_base = (mach64->linear_base & 0x800000) | (val << 24); - mach64_updatemapping(mach64); - break; - - case 0x15: - if (mach64->type == MACH64_VT2) - { - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_remove(mach64); - mach64->block_decoded_io = (mach64->block_decoded_io & 0xffff0000) | ((val & 0xfc) << 8); - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_set(mach64); - } - break; - case 0x16: - if (mach64->type == MACH64_VT2) - { - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_remove(mach64); - mach64->block_decoded_io = (mach64->block_decoded_io & 0xff00fc00) | (val << 16); - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_set(mach64); - } - break; - case 0x17: - if (mach64->type == MACH64_VT2) - { - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_remove(mach64); - mach64->block_decoded_io = (mach64->block_decoded_io & 0x00fffc00) | (val << 24); - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_set(mach64); - } - break; - - case 0x30: case 0x32: case 0x33: - mach64->pci_regs[addr] = val; - if (mach64->pci_regs[0x30] & 0x01) - { - uint32_t addr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24); - mach64_log("Mach64 bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&mach64->bios_rom.mapping, addr, 0x8000); - } - else - { - mach64_log("Mach64 bios_rom disabled\n"); - mem_mapping_disable(&mach64->bios_rom.mapping); - } - return; - - case 0x3c: - mach64->int_line = val; - break; - - case 0x40: - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_remove(mach64); - mach64->io_base = val & 0x03; - if (mach64->type == MACH64_VT2) - mach64->use_block_decoded_io = val & 0x04; - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_set(mach64); - break; - } -} - -static void *mach64_common_init(const device_t *info) -{ - mach64_t *mach64 = malloc(sizeof(mach64_t)); - memset(mach64, 0, sizeof(mach64_t)); - - mach64->vram_size = device_get_config_int("memory"); - mach64->vram_mask = (mach64->vram_size << 20) - 1; - - svga_init(&mach64->svga, mach64, mach64->vram_size << 20, - mach64_recalctimings, - mach64_in, mach64_out, - mach64_hwcursor_draw, - mach64_overlay_draw); - - if (info->flags & DEVICE_PCI) - mem_mapping_disable(&mach64->bios_rom.mapping); - - mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &mach64->svga); - mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); - mem_mapping_add(&mach64->mmio_linear_mapping_2, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); - mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); - mem_mapping_disable(&mach64->mmio_mapping); - - mach64_io_set(mach64); - - if (info->flags & DEVICE_PCI) - { - mach64->card = pci_add_card(PCI_ADD_VIDEO, mach64_pci_read, mach64_pci_write, mach64); - } - - mach64->pci_regs[PCI_REG_COMMAND] = 3; - mach64->pci_regs[0x30] = 0x00; - mach64->pci_regs[0x32] = 0x0c; - mach64->pci_regs[0x33] = 0x00; - - ati68860_ramdac_init(&mach64->ramdac); - - mach64->dst_cntl = 3; - - mach64->wake_fifo_thread = thread_create_event(); - mach64->fifo_not_full_event = thread_create_event(); - mach64->fifo_thread = thread_create(fifo_thread, mach64); - - return mach64; -} - -static void *mach64gx_init(const device_t *info) -{ - mach64_t *mach64 = mach64_common_init(info); - - mach64->type = MACH64_GX; - mach64->pci = !!(info->flags & DEVICE_PCI); - mach64->pci_id = (int)'X' | ((int)'G' << 8); - mach64->config_chip_id = 0x020000d7; - mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ - mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI-68860, 256Kx16 DRAM*/ - if (info->flags & DEVICE_PCI) - mach64->config_stat0 |= 0; /*PCI, 256Kx16 DRAM*/ - else if ((info->flags & DEVICE_VLB) || (info->flags & DEVICE_ISA)) - mach64->config_stat0 |= 1; /*VLB, 256Kx16 DRAM*/ - - ati_eeprom_load(&mach64->eeprom, L"mach64.nvr", 1); - - if (info->flags & DEVICE_PCI) - rom_init(&mach64->bios_rom, BIOS_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - else if (info->flags & DEVICE_VLB) - rom_init(&mach64->bios_rom, BIOS_VLB_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - else if (info->flags & DEVICE_ISA) - rom_init(&mach64->bios_rom, BIOS_ISA_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - return mach64; -} -static void *mach64vt2_init(const device_t *info) -{ - mach64_t *mach64 = mach64_common_init(info); - svga_t *svga = &mach64->svga; - - mach64->type = MACH64_VT2; - mach64->pci = 1; - mach64->pci_id = 0x5654; - mach64->config_chip_id = 0x40005654; - mach64->dac_cntl = 1 << 16; /*Internal 24-bit DAC*/ - mach64->config_stat0 = 4; - mach64->use_block_decoded_io = PCI ? 4 : 0; - - ati_eeprom_load(&mach64->eeprom, L"mach64vt.nvr", 1); - - rom_init(&mach64->bios_rom, BIOS_ROMVT2_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - svga->vblank_start = mach64_vblank_start; - - return mach64; -} - -int mach64gx_available(void) -{ - return rom_present(BIOS_ROM_PATH); -} -int mach64gx_isa_available(void) -{ - return rom_present(BIOS_ISA_ROM_PATH); -} -int mach64gx_vlb_available(void) -{ - return rom_present(BIOS_VLB_ROM_PATH); -} -int mach64vt2_available(void) -{ - return rom_present(BIOS_ROMVT2_PATH); -} - -void mach64_close(void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - - svga_close(&mach64->svga); - - thread_kill(mach64->fifo_thread); - thread_destroy_event(mach64->wake_fifo_thread); - thread_destroy_event(mach64->fifo_not_full_event); - - free(mach64); -} - -void mach64_speed_changed(void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - - svga_recalctimings(&mach64->svga); -} - -void mach64_force_redraw(void *p) -{ - mach64_t *mach64 = (mach64_t *)p; - - mach64->svga.fullchange = changeframecount; -} - -static const device_config_t mach64gx_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, - { - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -static const device_config_t mach64vt2_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, - { - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -const device_t mach64gx_isa_device = -{ - "ATI Mach64GX ISA", - DEVICE_AT | DEVICE_ISA, - 0, - mach64gx_init, mach64_close, NULL, - mach64gx_isa_available, - mach64_speed_changed, - mach64_force_redraw, - mach64gx_config -}; - -const device_t mach64gx_vlb_device = -{ - "ATI Mach64GX VLB", - DEVICE_VLB, - 0, - mach64gx_init, mach64_close, NULL, - mach64gx_vlb_available, - mach64_speed_changed, - mach64_force_redraw, - mach64gx_config -}; - -const device_t mach64gx_pci_device = -{ - "ATI Mach64GX PCI", - DEVICE_PCI, - 0, - mach64gx_init, mach64_close, NULL, - mach64gx_available, - mach64_speed_changed, - mach64_force_redraw, - mach64gx_config -}; - -const device_t mach64vt2_device = -{ - "ATI Mach64VT2", - DEVICE_PCI, - 0, - mach64vt2_init, mach64_close, NULL, - mach64vt2_available, - mach64_speed_changed, - mach64_force_redraw, - mach64vt2_config -}; diff --git a/backup code/video - Cópia/vid_ati_mach64.h b/backup code/video - Cópia/vid_ati_mach64.h deleted file mode 100644 index c44444d7a..000000000 --- a/backup code/video - Cópia/vid_ati_mach64.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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. - * - * ATi Mach64 graphics card emulation. - * - * Version: @(#)vid_ati_mach64.h 1.0.2 2018/03/18 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -extern const device_t mach64gx_isa_device; -extern const device_t mach64gx_vlb_device; -extern const device_t mach64gx_pci_device; -extern const device_t mach64vt2_device; diff --git a/backup code/video - Cópia/vid_bt485_ramdac.c b/backup code/video - Cópia/vid_bt485_ramdac.c deleted file mode 100644 index 80087044d..000000000 --- a/backup code/video - Cópia/vid_bt485_ramdac.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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. - * - * Brooktree BT485 true colour RAMDAC emulation. - * - * Currently only a dummy stub for logging and passing output - * to the generic SVGA handler. - * - * Version: @(#)vid_bt485_ramdac.c 1.0.2 2017/11/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_bt485_ramdac.h" - - -int bt485_get_clock_divider(bt485_ramdac_t *ramdac) -{ - return 1; /* Will be implemented later. */ -} - -void bt485_set_rs2(uint8_t rs2, bt485_ramdac_t *ramdac) -{ - ramdac->rs2 = rs2 ? 1 : 0; -} - -void bt485_set_rs3(uint8_t rs3, bt485_ramdac_t *ramdac) -{ - ramdac->rs3 = rs3 ? 1 : 0; -} - -void bt485_ramdac_out(uint16_t addr, uint8_t val, bt485_ramdac_t *ramdac, svga_t *svga) -{ -// /*if (CS!=0xC000) */pclog("OUT RAMDAC %04X %02X %i %04X:%04X %i\n",addr,val,sdac_ramdac.magic_count,CS,pc, sdac_ramdac.rs2); - uint8_t reg = addr & 3; - reg |= (ramdac->rs2 ? 4 : 0); - reg |= (ramdac->rs3 ? 8 : 0); - pclog("BT485 RAMDAC: Writing %02X to register %02X\n", val, reg); - svga_out(addr, val, svga); - return; - - switch (addr) - { - case 0x3C6: - if (val == 0xff) - { - ramdac->rs2 = 0; - ramdac->magic_count = 0; - break; - } - if (ramdac->magic_count < 4) break; - if (ramdac->magic_count == 4) - { - ramdac->command = val; -// pclog("RAMDAC command reg now %02X\n", val); - switch (val >> 4) - { - case 0x2: case 0x3: case 0xa: svga->bpp = 15; break; - case 0x4: case 0xe: svga->bpp = 24; break; - case 0x5: case 0x6: case 0xc: svga->bpp = 16; break; - case 0x7: svga->bpp = 32; break; - - case 0: case 1: default: svga->bpp = 8; break; - } - svga_recalctimings(svga); - } - //ramdac->magic_count = 0; - break; - - case 0x3C7: - ramdac->magic_count = 0; - if (ramdac->rs2) - ramdac->rindex = val; - break; - case 0x3C8: - ramdac->magic_count = 0; - if (ramdac->rs2) - ramdac->windex = val; - break; - case 0x3C9: - ramdac->magic_count = 0; - if (ramdac->rs2) - { - if (!ramdac->reg_ff) ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0xff00) | val; - else ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0x00ff) | (val << 8); - ramdac->reg_ff = !ramdac->reg_ff; -// pclog("RAMDAC reg %02X now %04X\n", ramdac->windex, ramdac->regs[ramdac->windex]); - if (!ramdac->reg_ff) ramdac->windex++; - } - break; - } - svga_out(addr, val, svga); -} - -uint8_t bt485_ramdac_in(uint16_t addr, bt485_ramdac_t *ramdac, svga_t *svga) -{ - uint8_t temp; -// /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i\n",addr,CS,pc, ramdac->rs2); - uint8_t reg = addr & 3; - reg |= (ramdac->rs2 ? 4 : 0); - reg |= (ramdac->rs3 ? 8 : 0); - pclog("BT485 RAMDAC: Reading register %02X\n", reg); - return svga_in(addr, svga); - - switch (addr) - { - case 0x3C6: - ramdac->reg_ff = 0; - if (ramdac->magic_count < 5) - ramdac->magic_count++; - if (ramdac->magic_count == 4) - { - temp = 0x70; /*SDAC ID*/ - ramdac->rs2 = 1; - } - if (ramdac->magic_count == 5) - { - temp = ramdac->command; - ramdac->magic_count = 0; - } - return temp; - case 0x3C7: -// if (ramdac->magic_count < 4) -// { - ramdac->magic_count=0; -// break; -// } - if (ramdac->rs2) return ramdac->rindex; - break; - case 0x3C8: -// if (ramdac->magic_count < 4) -// { - ramdac->magic_count=0; -// break; -// } - if (ramdac->rs2) return ramdac->windex; - break; - case 0x3C9: -// if (ramdac->magic_count < 4) -// { - ramdac->magic_count=0; -// break; -// } - if (ramdac->rs2) - { - if (!ramdac->reg_ff) temp = ramdac->regs[ramdac->rindex] & 0xff; - else temp = ramdac->regs[ramdac->rindex] >> 8; - ramdac->reg_ff = !ramdac->reg_ff; - if (!ramdac->reg_ff) - { - ramdac->rindex++; - ramdac->magic_count = 0; - } - return temp; - } - break; - } - return svga_in(addr, svga); -} - -float bt485_getclock(int clock, void *p) -{ - bt485_ramdac_t *ramdac = (bt485_ramdac_t *)p; - float t; - int m, n1, n2; -// pclog("SDAC_Getclock %i %04X\n", clock, ramdac->regs[clock]); - if (clock == 0) return 25175000.0; - if (clock == 1) return 28322000.0; - clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ - m = (ramdac->regs[clock] & 0x7f) + 2; - n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2; - n2 = ((ramdac->regs[clock] >> 13) & 0x07); - t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); -// pclog("BT485 clock %i %i %i %f %04X %f %i\n", m, n1, n2, t, ramdac->regs[2], 14318184.0 * ((float)m / (float)n1), 1 << n2); - return t; -} diff --git a/backup code/video - Cópia/vid_bt485_ramdac.h b/backup code/video - Cópia/vid_bt485_ramdac.h deleted file mode 100644 index 12d535359..000000000 --- a/backup code/video - Cópia/vid_bt485_ramdac.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ -typedef struct bt485_ramdac_t -{ - int magic_count; - uint8_t command; - int windex, rindex; - uint16_t regs[256]; - int reg_ff; - int rs2; - int rs3; -} bt485_ramdac_t; - -void bt485_ramdac_out(uint16_t addr, uint8_t val, bt485_ramdac_t *ramdac, svga_t *svga); -uint8_t bt485_ramdac_in(uint16_t addr, bt485_ramdac_t *ramdac, svga_t *svga); - -float bt485_getclock(int clock, void *p); diff --git a/backup code/video - Cópia/vid_cga.c b/backup code/video - Cópia/vid_cga.c deleted file mode 100644 index 6f12a01a5..000000000 --- a/backup code/video - Cópia/vid_cga.c +++ /dev/null @@ -1,598 +0,0 @@ -/* - * 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 old and new IBM CGA graphics cards. - * - * Version: @(#)vid_cga.c 1.0.16 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "video.h" -#include "vid_cga.h" -#include "vid_cga_comp.h" - - -#define CGA_RGB 0 -#define CGA_COMPOSITE 1 - -#define COMPOSITE_OLD 0 -#define COMPOSITE_NEW 1 - -static uint8_t crtcmask[32] = -{ - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -void cga_recalctimings(cga_t *cga); - -void cga_out(uint16_t addr, uint8_t val, void *p) -{ - cga_t *cga = (cga_t *)p; - uint8_t old; - switch (addr) - { - case 0x3D4: - cga->crtcreg = val & 31; - return; - case 0x3D5: - old = cga->crtc[cga->crtcreg]; - cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; - if (old != val) - { - if (cga->crtcreg < 0xe || cga->crtcreg > 0x10) - { - fullchange = changeframecount; - cga_recalctimings(cga); - } - } - return; - case 0x3D8: - if (((cga->cgamode ^ val) & 5) != 0) - { - cga->cgamode = val; - update_cga16_color(cga->cgamode); - } - - if ((cga->cgamode ^ val) & 1) - { - cga_palette = (cga->rgb_type << 1); - cgapal_rebuild(); - } - - cga->cgamode = val; - return; - case 0x3D9: - cga->cgacol = val; - return; - } -} - -uint8_t cga_in(uint16_t addr, void *p) -{ - cga_t *cga = (cga_t *)p; - switch (addr) - { - case 0x3D4: - return cga->crtcreg; - case 0x3D5: - return cga->crtc[cga->crtcreg]; - case 0x3DA: - return cga->cgastat; - } - return 0xFF; -} - -void cga_waitstates(void *p) -{ - cga_t *cga = (cga_t *)p; - int cycle = ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)); - - cycles -= 8 - (cycle & 7); - - cycle = ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)); - cycles -= 16 - (cycle & 15); - - cycle = ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)); - cycles -= 3 - (cycle % 3); -} - -void cga_write(uint32_t addr, uint8_t val, void *p) -{ - cga_t *cga = (cga_t *)p; - - cga->vram[addr & 0x3fff] = val; - if (cga->snow_enabled) - { - cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = val; - cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val; - } - egawrites++; - cga_waitstates(cga); -} - -uint8_t cga_read(uint32_t addr, void *p) -{ - cga_t *cga = (cga_t *)p; - cga_waitstates(cga); - if (cga->snow_enabled) - { - cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = cga->vram[addr & 0x3fff]; - cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = cga->vram[addr & 0x3fff]; - } - egareads++; - return cga->vram[addr & 0x3fff]; -} - -void cga_recalctimings(cga_t *cga) -{ - double disptime; - double _dispontime, _dispofftime; - if (cga->cgamode & 1) - { - disptime = (double) (cga->crtc[0] + 1); - _dispontime = (double) cga->crtc[1]; - } - else - { - disptime = (double) ((cga->crtc[0] + 1) << 1); - _dispontime = (double) (cga->crtc[1] << 1); - } - _dispofftime = disptime - _dispontime; - _dispontime = _dispontime * CGACONST; - _dispofftime = _dispofftime * CGACONST; - cga->dispontime = (int64_t)(_dispontime * (1LL << TIMER_SHIFT)); - cga->dispofftime = (int64_t)(_dispofftime * (1LL << TIMER_SHIFT)); -} - -void cga_poll(void *p) -{ - cga_t *cga = (cga_t *)p; - uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - uint16_t dat; - int cols[4]; - int col; - int oldsc; - - if (!cga->linepos) - { - cga->vidtime += cga->dispofftime; - cga->cgastat |= 1; - cga->linepos = 1; - oldsc = cga->sc; - if ((cga->crtc[8] & 3) == 3) - cga->sc = ((cga->sc << 1) + cga->oddeven) & 7; - if (cga->cgadispon) - { - if (cga->displine < cga->firstline) - { - cga->firstline = cga->displine; - video_wait_for_buffer(); - } - cga->lastline = cga->displine; - for (c = 0; c < 8; c++) - { - if ((cga->cgamode & 0x12) == 0x12) - { - buffer->line[cga->displine][c] = 0; - if (cga->cgamode & 1) buffer->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = 0; - else buffer->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = 0; - } - else - { - buffer->line[cga->displine][c] = (cga->cgacol & 15) + 16; - if (cga->cgamode & 1) buffer->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16; - else buffer->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16; - } - } - if (cga->cgamode & 1) - { - for (x = 0; x < cga->crtc[1]; x++) - { - chr = cga->charbuffer[x << 1]; - attr = cga->charbuffer[(x << 1) + 1]; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - if (cga->cgamode & 0x20) - { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; - if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) - cols[1] = cols[0]; - } - else - { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; - } - if (drawcursor) - { - for (c = 0; c < 8; c++) - buffer->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } - else - { - for (c = 0; c < 8; c++) - buffer->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - cga->ma++; - } - } - else if (!(cga->cgamode & 2)) - { - for (x = 0; x < cga->crtc[1]; x++) - { - chr = cga->vram[((cga->ma << 1) & 0x3fff)]; - attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)]; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - if (cga->cgamode & 0x20) - { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; - if ((cga->cgablink & 8) && (attr & 0x80)) cols[1] = cols[0]; - } - else - { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; - } - cga->ma++; - if (drawcursor) - { - for (c = 0; c < 8; c++) - buffer->line[cga->displine][(x << 4)+(c << 1) + 8] = buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } - else - { - for (c = 0; c < 8; c++) - buffer->line[cga->displine][(x << 4) + (c << 1) + 8] = buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } - else if (!(cga->cgamode & 16)) - { - cols[0] = (cga->cgacol & 15) | 16; - col = (cga->cgacol & 16) ? 24 : 16; - if (cga->cgamode & 4) - { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; - } - else if (cga->cgacol & 32) - { - cols[1] = col | 3; - cols[2] = col | 5; - cols[3] = col | 7; - } - else - { - cols[1] = col | 2; - cols[2] = col | 4; - cols[3] = col | 6; - } - for (x = 0; x < cga->crtc[1]; x++) - { - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; - cga->ma++; - for (c = 0; c < 8; c++) - { - buffer->line[cga->displine][(x << 4) + (c << 1) + 8] = - buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - } - else - { - cols[0] = 0; cols[1] = (cga->cgacol & 15) + 16; - for (x = 0; x < cga->crtc[1]; x++) - { - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; - cga->ma++; - for (c = 0; c < 16; c++) - { - buffer->line[cga->displine][(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - } - } - } - else - { - cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16; - if (cga->cgamode & 1) hline(buffer, 0, cga->displine, (cga->crtc[1] << 3) + 16, cols[0]); - else hline(buffer, 0, cga->displine, (cga->crtc[1] << 4) + 16, cols[0]); - } - - if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16; - else x = (cga->crtc[1] << 4) + 16; - - if (cga->composite) - { - for (c = 0; c < x; c++) - buffer32->line[cga->displine][c] = buffer->line[cga->displine][c] & 0xf; - - Composite_Process(cga->cgamode, 0, x >> 2, buffer32->line[cga->displine]); - } - - cga->sc = oldsc; - if (cga->vc == cga->crtc[7] && !cga->sc) - cga->cgastat |= 8; - cga->displine++; - if (cga->displine >= 360) - cga->displine = 0; - } - else - { - cga->vidtime += cga->dispontime; - cga->linepos = 0; - if (cga->vsynctime) - { - cga->vsynctime--; - if (!cga->vsynctime) - cga->cgastat &= ~8; - } - if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) - { - cga->con = 0; - cga->coff = 1; - } - if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1)) - cga->maback = cga->ma; - if (cga->vadj) - { - cga->sc++; - cga->sc &= 31; - cga->ma = cga->maback; - cga->vadj--; - if (!cga->vadj) - { - cga->cgadispon = 1; - cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; - cga->sc = 0; - } - } - else if (cga->sc == cga->crtc[9]) - { - cga->maback = cga->ma; - cga->sc = 0; - oldvc = cga->vc; - cga->vc++; - cga->vc &= 127; - - if (cga->vc == cga->crtc[6]) - cga->cgadispon = 0; - - if (oldvc == cga->crtc[4]) - { - cga->vc = 0; - cga->vadj = cga->crtc[5]; - if (!cga->vadj) cga->cgadispon = 1; - if (!cga->vadj) cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; - if ((cga->crtc[10] & 0x60) == 0x20) cga->cursoron = 0; - else cga->cursoron = cga->cgablink & 8; - } - - if (cga->vc == cga->crtc[7]) - { - cga->cgadispon = 0; - cga->displine = 0; - cga->vsynctime = 16; - if (cga->crtc[7]) - { - if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16; - else x = (cga->crtc[1] << 4) + 16; - cga->lastline++; - if ((x != xsize) || ((cga->lastline - cga->firstline) != ysize) || video_force_resize_get()) - { - xsize = x; - ysize = cga->lastline - cga->firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, (ysize << 1) + 16); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - - if (cga->composite) - video_blit_memtoscreen(0, cga->firstline - 4, 0, (cga->lastline - cga->firstline) + 8, xsize, (cga->lastline - cga->firstline) + 8); - else - video_blit_memtoscreen_8(0, cga->firstline - 4, 0, (cga->lastline - cga->firstline) + 8, xsize, (cga->lastline - cga->firstline) + 8); - frames++; - - video_res_x = xsize - 16; - video_res_y = ysize; - if (cga->cgamode & 1) - { - video_res_x /= 8; - video_res_y /= cga->crtc[9] + 1; - video_bpp = 0; - } - else if (!(cga->cgamode & 2)) - { - video_res_x /= 16; - video_res_y /= cga->crtc[9] + 1; - video_bpp = 0; - } - else if (!(cga->cgamode & 16)) - { - video_res_x /= 2; - video_bpp = 2; - } - else - { - video_bpp = 1; - } - } - cga->firstline = 1000; - cga->lastline = 0; - cga->cgablink++; - cga->oddeven ^= 1; - } - } - else - { - cga->sc++; - cga->sc &= 31; - cga->ma = cga->maback; - } - if (cga->cgadispon) - cga->cgastat &= ~1; - if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1)))) - cga->con = 1; - if (cga->cgadispon && (cga->cgamode & 1)) - { - for (x = 0; x < (cga->crtc[1] << 1); x++) - cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)]; - } - } -} - -void cga_init(cga_t *cga) -{ - cga->composite = 0; -} - -void *cga_standalone_init(const device_t *info) -{ - int display_type; - cga_t *cga = malloc(sizeof(cga_t)); - memset(cga, 0, sizeof(cga_t)); - - display_type = device_get_config_int("display_type"); - cga->composite = (display_type != CGA_RGB); - cga->revision = device_get_config_int("composite_type"); - cga->snow_enabled = device_get_config_int("snow_enabled"); - - cga->vram = malloc(0x4000); - - cga_comp_init(cga->revision); - timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); - mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, cga); - io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); - - overscan_x = overscan_y = 16; - - cga->rgb_type = device_get_config_int("rgb_type"); - cga_palette = (cga->rgb_type << 1); - cgapal_rebuild(); - - return cga; -} - -void cga_close(void *p) -{ - cga_t *cga = (cga_t *)p; - - free(cga->vram); - free(cga); -} - -void cga_speed_changed(void *p) -{ - cga_t *cga = (cga_t *)p; - - cga_recalctimings(cga); -} - -const device_config_t cga_config[] = -{ - { - "display_type", "Display type", CONFIG_SELECTION, "", CGA_RGB, - { - { - "RGB", CGA_RGB - }, - { - "Composite", CGA_COMPOSITE - }, - { - "" - } - } - }, - { - "composite_type", "Composite type", CONFIG_SELECTION, "", COMPOSITE_OLD, - { - { - "Old", COMPOSITE_OLD - }, - { - "New", COMPOSITE_NEW - }, - { - "" - } - } - }, - { - "rgb_type", "RGB type", CONFIG_SELECTION, "", 0, - { - { - "Color", 0 - }, - { - "Green Monochrome", 1 - }, - { - "Amber Monochrome", 2 - }, - { - "Gray Monochrome", 3 - }, - { - "Color (no brown)", 4 - }, - { - "" - } - } - }, - { - "snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } -}; - -const device_t cga_device = -{ - "CGA", - DEVICE_ISA, 0, - cga_standalone_init, - cga_close, - NULL, - NULL, - cga_speed_changed, - NULL, - cga_config -}; diff --git a/backup code/video - Cópia/vid_cga.h b/backup code/video - Cópia/vid_cga.h deleted file mode 100644 index 74aba09c2..000000000 --- a/backup code/video - Cópia/vid_cga.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 old and new IBM CGA graphics cards. - * - * Version: @(#)vid_cga.h 1.0.3 2018/03/18 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -typedef struct cga_t -{ - mem_mapping_t mapping; - - int crtcreg; - uint8_t crtc[32]; - - uint8_t cgastat; - - uint8_t cgamode, cgacol; - - int fontbase; - int linepos, displine; - int sc, vc; - int cgadispon; - int con, coff, cursoron, cgablink; - int vsynctime, vadj; - uint16_t ma, maback; - int oddeven; - - int64_t dispontime, dispofftime; - int64_t vidtime; - - int firstline, lastline; - - int drawcursor; - - uint8_t *vram; - - uint8_t charbuffer[256]; - - int revision; - int composite; - int snow_enabled; - int rgb_type; -} cga_t; - -void cga_init(cga_t *cga); -void cga_out(uint16_t addr, uint8_t val, void *p); -uint8_t cga_in(uint16_t addr, void *p); -void cga_write(uint32_t addr, uint8_t val, void *p); -uint8_t cga_read(uint32_t addr, void *p); -void cga_recalctimings(cga_t *cga); -void cga_poll(void *p); - -extern const device_config_t cga_config[]; -extern const device_t cga_device; diff --git a/backup code/video - Cópia/vid_cga_comp.c b/backup code/video - Cópia/vid_cga_comp.c deleted file mode 100644 index 008627bcd..000000000 --- a/backup code/video - Cópia/vid_cga_comp.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * 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. - * - * IBM CGA composite filter, borrowed from reenigne's DOSBox - * patch and ported to C. - * - * Version: @(#)vid_cga_comp.c 1.0.3 2017/11/04 - * - * Authors: reenigne, - * Miran Grca, - * - * Copyright 2015-2017 reenigne. - * Copyright 2015-2017 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "vid_cga.h" -#include "vid_cga_comp.h" - - -int CGA_Composite_Table[1024]; - - -static double brightness = 0; -static double contrast = 100; -static double saturation = 100; -static double sharpness = 0; -static double hue_offset = 0; - -/* New algorithm by reenigne - Works in all CGA modes/color settings and can simulate older and newer CGA revisions */ - -static const double tau = 6.28318531; /* == 2*pi */ - -static unsigned char chroma_multiplexer[256] = { - 2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4, - 133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152, - 2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5, - 140, 50, 54,100, 133,202, 57, 4, 2, 50,153,149, 128,198,198,135, - 32, 1, 36, 81, 147,158, 1, 42, 33, 1,210,254, 34,109,169, 77, - 177, 2, 0,165, 189,154, 3, 44, 33, 0, 91,197, 178,142,144,192, - 4, 2, 61, 67, 117,151,112, 83, 4, 0,249,255, 3,107,249,117, - 147, 1, 50,162, 143,141, 52, 54, 3, 0,145,206, 124,123,192,193, - 72, 78, 2, 0, 159,208, 4, 0, 53, 58,164,159, 37,159,171, 1, - 248,117, 4, 98, 212,218, 5, 2, 54, 59, 93,121, 176,181,134,130, - 1, 61, 31, 0, 160,255, 34, 1, 1, 58,197,166, 0,177,194, 2, - 162,111, 34, 96, 205,253, 32, 1, 1, 57,123,125, 119,188,150,112, - 78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37, - 252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200, - 61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107, - 198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252}; - -static double intensity[4] = { - 77.175381, 88.654656, 166.564623, 174.228438}; - -#define NEW_CGA(c,i,r,g,b) (((c)/0.72)*0.29 + ((i)/0.28)*0.32 + ((r)/0.28)*0.1 + ((g)/0.28)*0.22 + ((b)/0.28)*0.07) - -double mode_brightness; -double mode_contrast; -double mode_hue; -double min_v; -double max_v; - -double video_ri, video_rq, video_gi, video_gq, video_bi, video_bq; -int video_sharpness; -int tandy_mode_control = 0; - -static bool new_cga = 0; - -void update_cga16_color(uint8_t cgamode) { - int x; - double c, i, v; - double q, a, s, r; - double iq_adjust_i, iq_adjust_q; - double i0, i3, mode_saturation; - - static const double ri = 0.9563; - static const double rq = 0.6210; - static const double gi = -0.2721; - static const double gq = -0.6474; - static const double bi = -1.1069; - static const double bq = 1.7046; - - if (!new_cga) { - min_v = chroma_multiplexer[0] + intensity[0]; - max_v = chroma_multiplexer[255] + intensity[3]; - } - else { - i0 = intensity[0]; - i3 = intensity[3]; - min_v = NEW_CGA(chroma_multiplexer[0], i0, i0, i0, i0); - max_v = NEW_CGA(chroma_multiplexer[255], i3, i3, i3, i3); - } - mode_contrast = 256/(max_v - min_v); - mode_brightness = -min_v*mode_contrast; - if ((cgamode & 3) == 1) - mode_hue = 14; - else - mode_hue = 4; - - mode_contrast *= contrast * (new_cga ? 1.2 : 1)/100; /* new CGA: 120% */ - mode_brightness += (new_cga ? brightness-10 : brightness)*5; /* new CGA: -10 */ - mode_saturation = (new_cga ? 4.35 : 2.9)*saturation/100; /* new CGA: 150% */ - - for (x = 0; x < 1024; ++x) { - int phase = x & 3; - int right = (x >> 2) & 15; - int left = (x >> 6) & 15; - int rc = right; - int lc = left; - if ((cgamode & 4) != 0) { - rc = (right & 8) | ((right & 7) != 0 ? 7 : 0); - lc = (left & 8) | ((left & 7) != 0 ? 7 : 0); - } - c = chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase]; - i = intensity[(left >> 3) | ((right >> 2) & 2)]; - if (!new_cga) - v = c + i; - else { - double r = intensity[((left >> 2) & 1) | ((right >> 1) & 2)]; - double g = intensity[((left >> 1) & 1) | (right & 2)]; - double b = intensity[(left & 1) | ((right << 1) & 2)]; - v = NEW_CGA(c, i, r, g, b); - } - CGA_Composite_Table[x] = (int) (v*mode_contrast + mode_brightness); - } - - i = CGA_Composite_Table[6*68] - CGA_Composite_Table[6*68 + 2]; - q = CGA_Composite_Table[6*68 + 1] - CGA_Composite_Table[6*68 + 3]; - - a = tau*(33 + 90 + hue_offset + mode_hue)/360.0; - c = cos(a); - s = sin(a); - r = 256*mode_saturation/sqrt(i*i+q*q); - - iq_adjust_i = -(i*c + q*s)*r; - iq_adjust_q = (q*c - i*s)*r; - - video_ri = (int) (ri*iq_adjust_i + rq*iq_adjust_q); - video_rq = (int) (-ri*iq_adjust_q + rq*iq_adjust_i); - video_gi = (int) (gi*iq_adjust_i + gq*iq_adjust_q); - video_gq = (int) (-gi*iq_adjust_q + gq*iq_adjust_i); - video_bi = (int) (bi*iq_adjust_i + bq*iq_adjust_q); - video_bq = (int) (-bi*iq_adjust_q + bq*iq_adjust_i); - video_sharpness = (int) (sharpness*256/100); -} - -static Bit8u byte_clamp(int v) { - v >>= 13; - return v < 0 ? 0 : (v > 255 ? 255 : v); -} - -/* 2048x1536 is the maximum we can possibly support. */ -#define SCALER_MAXWIDTH 2048 - -static int temp[SCALER_MAXWIDTH + 10]={0}; -static int atemp[SCALER_MAXWIDTH + 2]={0}; -static int btemp[SCALER_MAXWIDTH + 2]={0}; - -Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine) -{ - int x; - Bit32u x2; - - int w = blocks*4; - - int *o; - Bit8u *rgbi; - int *b; - int *i; - Bit32u* srgb; - int *ap, *bp; - -#define COMPOSITE_CONVERT(I, Q) do { \ - i[1] = (i[1]<<3) - ap[1]; \ - a = ap[0]; \ - b = bp[0]; \ - c = i[0]+i[0]; \ - d = i[-1]+i[1]; \ - y = ((c+d)<<8) + video_sharpness*(c-d); \ - rr = y + video_ri*(I) + video_rq*(Q); \ - gg = y + video_gi*(I) + video_gq*(Q); \ - bb = y + video_bi*(I) + video_bq*(Q); \ - ++i; \ - ++ap; \ - ++bp; \ - *srgb = (byte_clamp(rr)<<16) | (byte_clamp(gg)<<8) | byte_clamp(bb); \ - ++srgb; \ -} while (0) - -#define OUT(v) do { *o = (v); ++o; } while (0) - - /* Simulate CGA composite output */ - o = temp; - rgbi = TempLine; - b = &CGA_Composite_Table[border*68]; - for (x = 0; x < 4; ++x) - OUT(b[(x+3)&3]); - OUT(CGA_Composite_Table[(border<<6) | ((*rgbi)<<2) | 3]); - for (x = 0; x < w-1; ++x) { - OUT(CGA_Composite_Table[(rgbi[0]<<6) | (rgbi[1]<<2) | (x&3)]); - ++rgbi; - } - OUT(CGA_Composite_Table[((*rgbi)<<6) | (border<<2) | 3]); - for (x = 0; x < 5; ++x) - OUT(b[x&3]); - - if ((cgamode & 4) != 0) { - /* Decode */ - i = temp + 5; - srgb = (Bit32u *)TempLine; - for (x2 = 0; x2 < blocks*4; ++x2) { - int c = (i[0]+i[0])<<3; - int d = (i[-1]+i[1])<<3; - int y = ((c+d)<<8) + video_sharpness*(c-d); - ++i; - *srgb = byte_clamp(y)*0x10101; - ++srgb; - } - } - else { - /* Store chroma */ - i = temp + 4; - ap = atemp + 1; - bp = btemp + 1; - for (x = -1; x < w + 1; ++x) { - ap[x] = i[-4]-((i[-2]-i[0]+i[2])<<1)+i[4]; - bp[x] = (i[-3]-i[-1]+i[1]-i[3])<<1; - ++i; - } - - /* Decode */ - i = temp + 5; - i[-1] = (i[-1]<<3) - ap[-1]; - i[0] = (i[0]<<3) - ap[0]; - srgb = (Bit32u *)TempLine; - for (x2 = 0; x2 < blocks; ++x2) { - int y,a,b,c,d,rr,gg,bb; - COMPOSITE_CONVERT(a, b); - COMPOSITE_CONVERT(-b, a); - COMPOSITE_CONVERT(-a, -b); - COMPOSITE_CONVERT(b, -a); - } - } -#undef COMPOSITE_CONVERT -#undef OUT - - return TempLine; -} - -void IncreaseHue(uint8_t cgamode) -{ - hue_offset += 5.0; - - update_cga16_color(cgamode); -} - -void DecreaseHue(uint8_t cgamode) -{ - hue_offset -= 5.0; - - update_cga16_color(cgamode); -} - -void IncreaseSaturation(uint8_t cgamode) -{ - saturation += 5; - - update_cga16_color(cgamode); -} - -void DecreaseSaturation(uint8_t cgamode) -{ - saturation -= 5; - - update_cga16_color(cgamode); -} - -void IncreaseContrast(uint8_t cgamode) -{ - contrast += 5; - - update_cga16_color(cgamode); -} - -void DecreaseContrast(uint8_t cgamode) -{ - contrast -= 5; - - update_cga16_color(cgamode); -} - -void IncreaseBrightness(uint8_t cgamode) -{ - brightness += 5; - - update_cga16_color(cgamode); -} - -void DecreaseBrightness(uint8_t cgamode) -{ - brightness -= 5; - - update_cga16_color(cgamode); -} - -void IncreaseSharpness(uint8_t cgamode) -{ - sharpness += 10; - - update_cga16_color(cgamode); -} - -void DecreaseSharpness(uint8_t cgamode) -{ - sharpness -= 10; - - update_cga16_color(cgamode); -} - -void cga_comp_init(int revision) -{ - new_cga = revision; - - /* Making sure this gets reset after reset. */ - brightness = 0; - contrast = 100; - saturation = 100; - sharpness = 0; - hue_offset = 0; - - update_cga16_color(0); -} diff --git a/backup code/video - Cópia/vid_cga_comp.h b/backup code/video - Cópia/vid_cga_comp.h deleted file mode 100644 index fbea172e7..000000000 --- a/backup code/video - Cópia/vid_cga_comp.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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. - * - * IBM CGA composite filter, borrowed from reenigne's DOSBox - * patch and ported to C. - * - * Version: @(#)vid_cga.h 1.0.0 2017/05/30 - * - * Author: reenigne, - * Miran Grca, - * Copyright 2015-2017 reenigne. - * Copyright 2015-2017 Miran Grca. - */ - -#define Bit8u uint8_t -#define Bit32u uint32_t -#define Bitu unsigned int -#define bool uint8_t - -void update_cga16_color(uint8_t cgamode); -void cga_comp_init(int revision); -Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine); diff --git a/backup code/video - Cópia/vid_cl54xx - Cópia.c b/backup code/video - Cópia/vid_cl54xx - Cópia.c deleted file mode 100644 index 3388b2647..000000000 --- a/backup code/video - Cópia/vid_cl54xx - Cópia.c +++ /dev/null @@ -1,2685 +0,0 @@ -/* - * 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 select Cirrus Logic cards (CL-GD 5428, - * CL-GD 5429, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). - * - * Version: @(#)vid_cl_54xx.c 1.0.19 2018/05/08 - * - * Authors: Sarah Walker, - * Barry Rodewald, - * TheCollector1995, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2018 Barry Rodewald - * Copyright 2016-2018 TheCollector1995. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_svga_render.h" -#include "vid_cl54xx.h" - -#define BIOS_GD5426_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin" -#define BIOS_GD5428_ISA_PATH L"roms/video/cirruslogic/5428.bin" -#define BIOS_GD5428_PATH L"roms/video/cirruslogic/vlbusjapan.BIN" -#define BIOS_GD5429_PATH L"roms/video/cirruslogic/5429.vbi" -#define BIOS_GD5430_VLB_PATH L"roms/video/cirruslogic/diamondvlbus.bin" -#define BIOS_GD5430_PCI_PATH L"roms/video/cirruslogic/pci.bin" -#define BIOS_GD5434_PATH L"roms/video/cirruslogic/gd5434.bin" -#define BIOS_GD5436_PATH L"roms/video/cirruslogic/5436.vbi" -#define BIOS_GD5440_PATH L"roms/video/cirruslogic/BIOS.BIN" -#define BIOS_GD5446_PATH L"roms/video/cirruslogic/5446BV.VBI" -#define BIOS_GD5446_STB_PATH L"roms/video/cirruslogic/stb nitro64v.BIN" -#define BIOS_GD5480_PATH L"roms/video/cirruslogic/clgd5480.rom" - -#define CIRRUS_ID_CLGD5426 0x90 -#define CIRRUS_ID_CLGD5428 0x98 -#define CIRRUS_ID_CLGD5429 0x9c -#define CIRRUS_ID_CLGD5430 0xa0 -#define CIRRUS_ID_CLGD5434 0xa8 -#define CIRRUS_ID_CLGD5436 0xac -#define CIRRUS_ID_CLGD5440 0xa0 /* Yes, the 5440 has the same ID as the 5430. */ -#define CIRRUS_ID_CLGD5446 0xb8 -#define CIRRUS_ID_CLGD5480 0xbc - -/* sequencer 0x07 */ -#define CIRRUS_SR7_BPP_VGA 0x00 -#define CIRRUS_SR7_BPP_SVGA 0x01 -#define CIRRUS_SR7_BPP_MASK 0x0e -#define CIRRUS_SR7_BPP_8 0x00 -#define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02 -#define CIRRUS_SR7_BPP_24 0x04 -#define CIRRUS_SR7_BPP_16 0x06 -#define CIRRUS_SR7_BPP_32 0x08 -#define CIRRUS_SR7_ISAADDR_MASK 0xe0 - -/* sequencer 0x12 */ -#define CIRRUS_CURSOR_SHOW 0x01 -#define CIRRUS_CURSOR_HIDDENPEL 0x02 -#define CIRRUS_CURSOR_LARGE 0x04 /* 64x64 if set, 32x32 if clear */ - -// sequencer 0x17 -#define CIRRUS_BUSTYPE_VLBFAST 0x10 -#define CIRRUS_BUSTYPE_PCI 0x20 -#define CIRRUS_BUSTYPE_VLBSLOW 0x30 -#define CIRRUS_BUSTYPE_ISA 0x38 -#define CIRRUS_MMIO_ENABLE 0x04 -#define CIRRUS_MMIO_USE_PCIADDR 0x40 /* 0xb8000 if cleared. */ -#define CIRRUS_MEMSIZEEXT_DOUBLE 0x80 - -// control 0x0b -#define CIRRUS_BANKING_DUAL 0x01 -#define CIRRUS_BANKING_GRANULARITY_16K 0x20 /* set:16k, clear:4k */ - -/* control 0x30 */ -#define CIRRUS_BLTMODE_BACKWARDS 0x01 -#define CIRRUS_BLTMODE_MEMSYSDEST 0x02 -#define CIRRUS_BLTMODE_MEMSYSSRC 0x04 -#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08 -#define CIRRUS_BLTMODE_PATTERNCOPY 0x40 -#define CIRRUS_BLTMODE_COLOREXPAND 0x80 -#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30 -#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00 -#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10 -#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20 -#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30 - -// control 0x31 -#define CIRRUS_BLT_BUSY 0x01 -#define CIRRUS_BLT_START 0x02 -#define CIRRUS_BLT_RESET 0x04 -#define CIRRUS_BLT_FIFOUSED 0x10 -#define CIRRUS_BLT_AUTOSTART 0x80 - -// control 0x33 -#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04 -#define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02 -#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01 - -#define CL_GD5429_SYSTEM_BUS_VESA 5 -#define CL_GD5429_SYSTEM_BUS_ISA 7 - -#define CL_GD543X_SYSTEM_BUS_PCI 4 -#define CL_GD543X_SYSTEM_BUS_VESA 6 -#define CL_GD543X_SYSTEM_BUS_ISA 7 - -typedef struct gd54xx_t -{ - mem_mapping_t mmio_mapping; - mem_mapping_t linear_mapping; - - svga_t svga; - - int has_bios, rev; - rom_t bios_rom; - - uint32_t vram_size; - uint32_t vram_mask; - - uint8_t vclk_n[4]; - uint8_t vclk_d[4]; - uint32_t bank[2]; - - struct { - uint8_t state; - int ctrl; - } ramdac; - - struct { - uint32_t fg_col, bg_col; - uint16_t width, height; - uint16_t dst_pitch, src_pitch; - uint32_t dst_addr, src_addr; - uint8_t mask, mode, rop; - uint8_t modeext; - uint8_t status; - uint16_t trans_col, trans_mask; - - uint32_t dst_addr_backup, src_addr_backup; - uint16_t width_backup, height_internal; - - int x_count, y_count; - int sys_tx; - uint8_t sys_cnt; - uint32_t sys_buf; - uint16_t pixel_cnt; - uint16_t scan_cnt; - } blt; - - int pci, vlb; - - uint8_t pci_regs[256]; - uint8_t int_line; - - int card; - - uint32_t lfb_base; - - int mmio_vram_overlap; - - uint32_t extpallook[256]; - PALETTE extpal; -} gd54xx_t; - -static void -gd543x_mmio_write(uint32_t addr, uint8_t val, void *p); -static void -gd543x_mmio_writew(uint32_t addr, uint16_t val, void *p); -static void -gd543x_mmio_writel(uint32_t addr, uint32_t val, void *p); -static uint8_t -gd543x_mmio_read(uint32_t addr, void *p); -static uint16_t -gd543x_mmio_readw(uint32_t addr, void *p); -static uint32_t -gd543x_mmio_readl(uint32_t addr, void *p); - -static void -gd54xx_recalc_banking(gd54xx_t *gd54xx); - -static void -gd543x_recalc_mapping(gd54xx_t *gd54xx); - -static void -gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga); - - -/* Returns 1 if the card is a 5434, 5436/46, or 5480. */ -static int -gd54xx_is_5434(svga_t *svga) -{ - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) - return 1; - else - return 0; -} - - -static void -gd54xx_out(uint16_t addr, uint8_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - uint8_t old; - int c; - uint8_t o; - uint32_t o32; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) { - case 0x3c0: - case 0x3c1: - if (!svga->attrff) { - svga->attraddr = val & 31; - if ((val & 0x20) != svga->attr_palette_enable) { - svga->fullchange = 3; - svga->attr_palette_enable = val & 0x20; - svga_recalctimings(svga); - } - } else { - o = svga->attrregs[svga->attraddr & 31]; - svga->attrregs[svga->attraddr & 31] = val; - if (svga->attraddr < 16) - svga->fullchange = changeframecount; - if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { - for (c = 0; c < 16; c++) { - if (svga->attrregs[0x10] & 0x80) svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); - else svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); - } - } - /* Recalculate timings on change of attribute register 0x11 (overscan border color) too. */ - if (svga->attraddr == 0x10) { - if (o != val) - svga_recalctimings(svga); - } else if (svga->attraddr == 0x11) { - if (!(svga->seqregs[0x12] & 0x80)) { - svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; - if (o != val) svga_recalctimings(svga); - } - } else if (svga->attraddr == 0x12) { - if ((val & 0xf) != svga->plane_mask) - svga->fullchange = changeframecount; - svga->plane_mask = val & 0xf; - } - } - svga->attrff ^= 1; - return; - case 0x3c4: - svga->seqaddr = val; - break; - case 0x3c5: - if (svga->seqaddr > 5) { - o = svga->seqregs[svga->seqaddr & 0x1f]; - svga->seqregs[svga->seqaddr & 0x1f] = val; - switch (svga->seqaddr & 0x1f) { - case 6: - val &= 0x17; - if (val == 0x12) - svga->seqregs[6] = 0x12; - else - svga->seqregs[6] = 0x0f; - break; - case 0x0b: case 0x0c: case 0x0d: case 0x0e: /* VCLK stuff */ - gd54xx->vclk_n[svga->seqaddr-0x0b] = val; - break; - case 0x1b: case 0x1c: case 0x1d: case 0x1e: /* VCLK stuff */ - gd54xx->vclk_d[svga->seqaddr-0x1b] = val; - break; - case 0x10: case 0x30: case 0x50: case 0x70: - case 0x90: case 0xb0: case 0xd0: case 0xf0: - svga->hwcursor.x = (val << 3) | (svga->seqaddr >> 5); - break; - case 0x11: case 0x31: case 0x51: case 0x71: - case 0x91: case 0xb1: case 0xd1: case 0xf1: - svga->hwcursor.y = (val << 3) | (svga->seqaddr >> 5); - break; - case 0x12: - if (val & 0x80) - svga->overscan_color = gd54xx->extpallook[2]; - else - svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; - svga_recalctimings(svga); - svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW; - svga->hwcursor.xsize = svga->hwcursor.ysize = (val & CIRRUS_CURSOR_LARGE) ? 64 : 32; - if (val & CIRRUS_CURSOR_LARGE) - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256)); - else - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3f) * 256)); - break; - case 0x13: - if (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3c) * 256)); - else - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3f) * 256)); - break; - case 0x07: - svga->set_reset_disabled = svga->seqregs[7] & 1; - case 0x17: - gd543x_recalc_mapping(gd54xx); - break; - } - return; - } - break; - case 0x3C6: - if (gd54xx->ramdac.state == 4) { - gd54xx->ramdac.state = 0; - gd54xx->ramdac.ctrl = val; - svga_recalctimings(svga); - return; - } - gd54xx->ramdac.state = 0; - break; - case 0x3C9: - 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: - if (svga->seqregs[0x12] & 2) { - gd54xx->extpal[svga->dac_write].r = svga->dac_r; - gd54xx->extpal[svga->dac_write].g = svga->dac_g; - gd54xx->extpal[svga->dac_write].b = val; - gd54xx->extpallook[svga->dac_write & 15] = makecol32(video_6to8[gd54xx->extpal[svga->dac_write].r & 0x3f], video_6to8[gd54xx->extpal[svga->dac_write].g & 0x3f], video_6to8[gd54xx->extpal[svga->dac_write].b & 0x3f]); - if ((svga->seqregs[0x12] & 0x80) && ((svga->dac_write & 15) == 2)) { - o32 = svga->overscan_color; - svga->overscan_color = gd54xx->extpallook[2]; - if (o32 != svga->overscan_color) - svga_recalctimings(svga); - } - svga->dac_write = (svga->dac_write + 1) & 15; - } else { - svga->vgapal[svga->dac_write].r = svga->dac_r; - svga->vgapal[svga->dac_write].g = svga->dac_g; - svga->vgapal[svga->dac_write].b = val; - svga->pallook[svga->dac_write] = makecol32(video_6to8[svga->vgapal[svga->dac_write].r & 0x3f], video_6to8[svga->vgapal[svga->dac_write].g & 0x3f], video_6to8[svga->vgapal[svga->dac_write].b & 0x3f]); - svga->dac_write = (svga->dac_write + 1) & 255; - } - svga->dac_pos = 0; - break; - } - return; - case 0x3cf: - if (svga->gdcaddr == 0) - gd543x_mmio_write(0xb8000, val, gd54xx); - if (svga->gdcaddr == 1) - gd543x_mmio_write(0xb8004, val, gd54xx); - - if (svga->gdcaddr == 5) { - svga->gdcreg[5] = val; - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = svga->gdcreg[5] & 7; - else - svga->writemode = svga->gdcreg[5] & 3; - svga->readmode = val & 8; - svga->chain2_read = val & 0x10; - return; - } - - if (svga->gdcaddr == 6) { - if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { - svga->gdcreg[6] = val; - gd543x_recalc_mapping(gd54xx); - } - svga->gdcreg[6] = val; - return; - } - - if (svga->gdcaddr > 8) { - svga->gdcreg[svga->gdcaddr & 0x3f] = val; - switch (svga->gdcaddr) { - case 0x09: case 0x0a: case 0x0b: - gd54xx_recalc_banking(gd54xx); - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = svga->gdcreg[5] & 7; - else - svga->writemode = svga->gdcreg[5] & 3; - break; - - case 0x10: - gd543x_mmio_write(0xb8001, val, gd54xx); - break; - case 0x11: - gd543x_mmio_write(0xb8005, val, gd54xx); - break; - case 0x12: - gd543x_mmio_write(0xb8002, val, gd54xx); - break; - case 0x13: - gd543x_mmio_write(0xb8006, val, gd54xx); - break; - case 0x14: - gd543x_mmio_write(0xb8003, val, gd54xx); - break; - case 0x15: - gd543x_mmio_write(0xb8007, val, gd54xx); - break; - - case 0x20: - gd543x_mmio_write(0xb8008, val, gd54xx); - break; - case 0x21: - gd543x_mmio_write(0xb8009, val, gd54xx); - break; - case 0x22: - gd543x_mmio_write(0xb800a, val, gd54xx); - break; - case 0x23: - gd543x_mmio_write(0xb800b, val, gd54xx); - break; - case 0x24: - gd543x_mmio_write(0xb800c, val, gd54xx); - break; - case 0x25: - gd543x_mmio_write(0xb800d, val, gd54xx); - break; - case 0x26: - gd543x_mmio_write(0xb800e, val, gd54xx); - break; - case 0x27: - gd543x_mmio_write(0xb800f, val, gd54xx); - break; - - case 0x28: - gd543x_mmio_write(0xb8010, val, gd54xx); - break; - case 0x29: - gd543x_mmio_write(0xb8011, val, gd54xx); - break; - case 0x2a: - gd543x_mmio_write(0xb8012, val, gd54xx); - break; - - case 0x2c: - gd543x_mmio_write(0xb8014, val, gd54xx); - break; - case 0x2d: - gd543x_mmio_write(0xb8015, val, gd54xx); - break; - case 0x2e: - gd543x_mmio_write(0xb8016, val, gd54xx); - break; - - case 0x2f: - gd543x_mmio_write(0xb8017, val, gd54xx); - break; - case 0x30: - gd543x_mmio_write(0xb8018, val, gd54xx); - break; - - case 0x32: - gd543x_mmio_write(0xb801a, val, gd54xx); - break; - - case 0x33: - gd543x_mmio_write(0xb801b, val, gd54xx); - break; - - case 0x31: - gd543x_mmio_write(0xb8040, val, gd54xx); - break; - - case 0x34: - gd543x_mmio_write(0xb801c, val, gd54xx); - break; - - case 0x35: - gd543x_mmio_write(0xb801d, val, gd54xx); - break; - - case 0x38: - gd543x_mmio_write(0xb8020, val, gd54xx); - break; - - case 0x39: - gd543x_mmio_write(0xb8021, val, gd54xx); - break; - - } - return; - } - break; - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); -} - - -static uint8_t -gd54xx_in(uint16_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - uint8_t temp; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3d0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) { - case 0x3c4: - if ((svga->seqregs[6] & 0x17) == 0x12) - { - temp = svga->seqaddr; - if ((temp & 0x1e) == 0x10) - { - if (temp & 1) - temp = ((svga->hwcursor.y & 7) << 5) | 0x11; - else - temp = ((svga->hwcursor.x & 7) << 5) | 0x10; - } - return temp; - } - return svga->seqaddr; - - case 0x3c5: - if (svga->seqaddr > 5) { - switch (svga->seqaddr) { - case 6: - return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; - case 0x0b: case 0x0c: case 0x0d: case 0x0e: - return gd54xx->vclk_n[svga->seqaddr-0x0b]; - case 0x17: - temp = svga->gdcreg[0x17] & ~(7 << 3); - if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) { - if (gd54xx->vlb) - temp |= (CL_GD5429_SYSTEM_BUS_VESA << 3); - else - temp |= (CL_GD5429_SYSTEM_BUS_ISA << 3); - } else { - if (gd54xx->pci) - temp |= (CL_GD543X_SYSTEM_BUS_PCI << 3); - else if (gd54xx->vlb) - temp |= (CL_GD543X_SYSTEM_BUS_VESA << 3); - else - temp |= (CL_GD543X_SYSTEM_BUS_ISA << 3); - } - return temp; - case 0x1b: case 0x1c: case 0x1d: case 0x1e: - return gd54xx->vclk_d[svga->seqaddr-0x1b]; - } - return svga->seqregs[svga->seqaddr & 0x3f]; - } - break; - case 0x3c9: - svga->dac_status = 3; - switch (svga->dac_pos) { - case 0: - svga->dac_pos++; - if (svga->seqregs[0x12] & 2) - return gd54xx->extpal[svga->dac_read].r & 0x3f; - else - return svga->vgapal[svga->dac_read].r & 0x3f; - case 1: - svga->dac_pos++; - if (svga->seqregs[0x12] & 2) - return gd54xx->extpal[svga->dac_read].g & 0x3f; - else - return svga->vgapal[svga->dac_read].g & 0x3f; - case 2: - svga->dac_pos=0; - if (svga->seqregs[0x12] & 2) { - svga->dac_read = (svga->dac_read + 1) & 15; - return gd54xx->extpal[(svga->dac_read - 1) & 15].b & 0x3f; - } else { - svga->dac_read = (svga->dac_read + 1) & 255; - return svga->vgapal[(svga->dac_read - 1) & 255].b & 0x3f; - } - } - return 0xFF; - case 0x3C6: - if (gd54xx->ramdac.state == 4) { - gd54xx->ramdac.state = 0; - return gd54xx->ramdac.ctrl; - } - gd54xx->ramdac.state++; - break; - case 0x3cf: - if (svga->gdcaddr > 8) { - return svga->gdcreg[svga->gdcaddr & 0x3f]; - } - break; - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - switch (svga->crtcreg) { - case 0x24: /*Attribute controller toggle readback (R)*/ - return svga->attrff << 7; - case 0x26: /*Attribute controller index readback (R)*/ - return svga->attraddr & 0x3f; - case 0x27: /*ID*/ - return svga->crtc[0x27]; /*GD542x/GD543x*/ - case 0x28: /*Class ID*/ - if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5430) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5440)) - return 0xff; /*Standard CL-GD5430/40*/ - break; - } - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); -} - - -static void -gd54xx_recalc_banking(gd54xx_t *gd54xx) -{ - svga_t *svga = &gd54xx->svga; - - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) - gd54xx->bank[0] = svga->gdcreg[0x09] << 14; - else - gd54xx->bank[0] = svga->gdcreg[0x09] << 12; - - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) { - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) - gd54xx->bank[1] = svga->gdcreg[0x0a] << 14; - else - gd54xx->bank[1] = svga->gdcreg[0x0a] << 12; - } else - gd54xx->bank[1] = gd54xx->bank[0] + 0x8000; -} - - -static void -gd543x_recalc_mapping(gd54xx_t *gd54xx) -{ - svga_t *svga = &gd54xx->svga; - - if (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&gd54xx->linear_mapping); - mem_mapping_disable(&gd54xx->mmio_mapping); - return; - } - - gd54xx->mmio_vram_overlap = 0; - - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_disable(&gd54xx->linear_mapping); - switch (svga->gdcreg[6] & 0x0c) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - gd54xx->mmio_vram_overlap = 1; - break; - } - if (svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) - mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x00100); - else - mem_mapping_disable(&gd54xx->mmio_mapping); - } else { - uint32_t base, size; - - if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429 || (!gd54xx->pci && !gd54xx->vlb)) { - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) { - base = (svga->seqregs[7] & 0xf0) << 16; - size = 1 * 1024 * 1024; - } else { - base = (svga->seqregs[7] & 0xe0) << 16; - size = 2 * 1024 * 1024; - } - } else if (gd54xx->pci) { - base = gd54xx->lfb_base; - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - size = 16 * 1024 * 1024; - else - size = 4 * 1024 * 1024; - } else { /*VLB*/ - base = 128*1024*1024; - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - size = 16 * 1024 * 1024; - else - size = 4 * 1024 * 1024; - } - - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&gd54xx->linear_mapping, base, size); - if (svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) { - if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) { - if (size >= (4 * 1024 * 1024)) - mem_mapping_disable(&gd54xx->mmio_mapping); /* MMIO is handled in the linear read/write functions */ - else { - mem_mapping_set_addr(&gd54xx->linear_mapping, base, size - 256); - mem_mapping_set_addr(&gd54xx->mmio_mapping, base + size - 256, 0x00100); - } - } else - mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x00100); - } else - mem_mapping_disable(&gd54xx->mmio_mapping); - } -} - - -static void -gd54xx_recalctimings(svga_t *svga) -{ - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - uint8_t clocksel; - - svga->rowoffset = (svga->crtc[0x13]) | ((svga->crtc[0x1b] & 0x10) << 4); - - svga->interlace = (svga->crtc[0x1a] & 0x01); - - if (svga->seqregs[7] & CIRRUS_SR7_BPP_SVGA) - svga->render = svga_render_8bpp_highres; - else if (svga->gdcreg[5] & 0x40) - svga->render = svga_render_8bpp_lowres; - - svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); - - svga->bpp = 8; - - if (gd54xx->ramdac.ctrl & 0x80) { - if (gd54xx->ramdac.ctrl & 0x40) { - switch (gd54xx->ramdac.ctrl & 0xf) { - case 0: - svga->bpp = 15; - svga->render = svga_render_15bpp_highres; - break; - - case 1: - svga->bpp = 16; - svga->render = svga_render_16bpp_highres; - break; - - case 5: - if (gd54xx_is_5434(svga) && (svga->seqregs[7] & CIRRUS_SR7_BPP_32)) { - svga->bpp = 32; - svga->render = svga_render_32bpp_highres; - if (svga->crtc[0x27] < CIRRUS_ID_CLGD5436) - svga->rowoffset *= 2; - } else { - svga->bpp = 24; - svga->render = svga_render_24bpp_highres; - } - break; - - case 0xf: - switch (svga->seqregs[7] & CIRRUS_SR7_BPP_MASK) { - case CIRRUS_SR7_BPP_32: - svga->bpp = 32; - svga->render = svga_render_32bpp_highres; - svga->rowoffset *= 2; - break; - - case CIRRUS_SR7_BPP_24: - svga->bpp = 24; - svga->render = svga_render_24bpp_highres; - break; - - case CIRRUS_SR7_BPP_16: - case CIRRUS_SR7_BPP_16_DOUBLEVCLK: - svga->bpp = 16; - svga->render = svga_render_16bpp_highres; - break; - - case CIRRUS_SR7_BPP_8: - svga->bpp = 8; - svga->render = svga_render_8bpp_highres; - break; - } - break; - } - } else { - svga->bpp = 15; - svga->render = svga_render_15bpp_highres; - } - } - - clocksel = (svga->miscout >> 2) & 3; - - if (!gd54xx->vclk_n[clocksel] || !gd54xx->vclk_d[clocksel]) - svga->clock = cpuclock / ((svga->miscout & 0xc) ? 28322000.0 : 25175000.0); - else { - int n = gd54xx->vclk_n[clocksel] & 0x7f; - int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; - int m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; - float freq = (14318184.0 * ((float)n / ((float)d * m))); - switch (svga->seqregs[7] & (gd54xx_is_5434(svga) ? 0xe : 6)) { - case 2: - freq /= 2.0; - break; - case 4: - if (!gd54xx_is_5434(svga)) - freq /= 3.0; - break; - } - svga->clock = cpuclock / freq; - } - - svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff; -} - -static -void gd54xx_hwcursor_draw(svga_t *svga, int displine) -{ - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - int x, xx, comb, b0, b1; - uint8_t dat[2]; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - int pitch = (svga->hwcursor.xsize == 64) ? 16 : 4; - uint32_t bgcol = gd54xx->extpallook[0x00]; - uint32_t fgcol = gd54xx->extpallook[0x0f]; - - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; - - for (x = 0; x < svga->hwcursor.xsize; x += 8) { - dat[0] = svga->vram[svga->hwcursor_latch.addr]; - if (svga->hwcursor.xsize == 64) - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x08]; - else - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; - for (xx = 0; xx < 8; xx++) { - b0 = (dat[0] >> (7 - xx)) & 1; - b1 = (dat[1] >> (7 - xx)) & 1; - comb = (b1 | (b0 << 1)); - if (offset >= svga->hwcursor_latch.x) { - switch(comb) { - case 0: - /* The original screen pixel is shown (invisible cursor) */ - break; - case 1: - /* The pixel is shown in the cursor background color */ - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = bgcol; - break; - case 2: - /* The pixel is shown as the inverse of the original screen pixel - (XOR cursor) */ - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; - break; - case 3: - /* The pixel is shown in the cursor foreground color */ - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = fgcol; - break; - } - } - - offset++; - } - svga->hwcursor_latch.addr++; - } - - if (svga->hwcursor.xsize == 64) - svga->hwcursor_latch.addr += 8; - - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; -} - -static void -gd54xx_memsrc_rop(gd54xx_t *gd54xx, svga_t *svga, uint8_t src, uint8_t dst) -{ - uint8_t res = src; - svga->changedvram[(gd54xx->blt.dst_addr_backup & svga->vram_mask) >> 12] = changeframecount; - - switch (gd54xx->blt.rop) { - case 0x00: res = 0; break; - case 0x05: res = src & dst; break; - case 0x06: res = dst; break; - case 0x09: res = src & ~dst; break; - case 0x0b: res = ~ dst; break; - case 0x0d: res = src; break; - case 0x0e: res = 0xff; break; - case 0x50: res = ~ src & dst; break; - case 0x59: res = src ^ dst; break; - case 0x6d: res = src | dst; break; - case 0x90: res = ~(src | dst); break; - case 0x95: res = ~(src ^ dst); break; - case 0xad: res = src | ~dst; break; - case 0xd0: res = ~src; break; - case 0xd6: res = ~src | dst; break; - case 0xda: res = ~(src & dst); break; - } - - /* handle transparency compare */ - if(gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { /* TODO: 16-bit compare */ - /* if ROP result matches the transparency colour, don't change the pixel */ - if((res & (~gd54xx->blt.trans_mask & 0xff)) == ((gd54xx->blt.trans_col & 0xff) & (~gd54xx->blt.trans_mask & 0xff))) - return; - } - - svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask] = res; -} - - -/* non colour-expanded BitBLTs from system memory must be doubleword sized, extra bytes are ignored */ -static void -gd54xx_blit_dword(gd54xx_t *gd54xx, svga_t *svga) -{ - /* TODO: add support for reverse direction */ - uint8_t x, pixel; - - for (x=0;x<32;x+=8) { - pixel = ((gd54xx->blt.sys_buf & (0xff << x)) >> x); - if(gd54xx->blt.pixel_cnt <= gd54xx->blt.width) - gd54xx_memsrc_rop(gd54xx, svga, pixel, svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask]); - gd54xx->blt.dst_addr_backup++; - gd54xx->blt.pixel_cnt++; - } - if (gd54xx->blt.pixel_cnt > gd54xx->blt.width) { - gd54xx->blt.pixel_cnt = 0; - gd54xx->blt.scan_cnt++; - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr + (gd54xx->blt.dst_pitch*gd54xx->blt.scan_cnt); - } - if (gd54xx->blt.scan_cnt > gd54xx->blt.height) { - gd54xx->blt.sys_tx = 0; /* BitBLT complete */ - gd543x_recalc_mapping(gd54xx); - } -} - - -static void -gd54xx_blt_write_w(uint32_t addr, uint16_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - gd54xx_start_blit(val, 16, gd54xx, &gd54xx->svga); -} - - -static void -gd54xx_blt_write_l(uint32_t addr, uint32_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) == (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) { - gd54xx_start_blit(val & 0xff, 8, gd54xx, &gd54xx->svga); - gd54xx_start_blit((val>>8) & 0xff, 8, gd54xx, &gd54xx->svga); - gd54xx_start_blit((val>>16) & 0xff, 8, gd54xx, &gd54xx->svga); - gd54xx_start_blit((val>>24) & 0xff, 8, gd54xx, &gd54xx->svga); - } else - gd54xx_start_blit(val, 32, gd54xx, &gd54xx->svga); -} - - -static void -gd54xx_write(uint32_t addr, uint8_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd54xx->blt.sys_tx) { - if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { - gd54xx->blt.sys_buf &= ~(0xff << (gd54xx->blt.sys_cnt * 8)); - gd54xx->blt.sys_buf |= (val << (gd54xx->blt.sys_cnt * 8)); - gd54xx->blt.sys_cnt++; - if(gd54xx->blt.sys_cnt >= 4) { - gd54xx_blit_dword(gd54xx, svga); - gd54xx->blt.sys_cnt = 0; - } - } - return; - } - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - - svga_write_linear(addr, val, svga); -} - - -static void -gd54xx_writew(uint32_t addr, uint16_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd54xx->blt.sys_tx) - { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - return; - } - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - - if (svga->writemode < 4) - svga_writew_linear(addr, val, svga); - else { - svga_write_linear(addr, val, svga); - svga_write_linear(addr + 1, val >> 8, svga); - } -} - - -static void -gd54xx_writel(uint32_t addr, uint32_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd54xx->blt.sys_tx) - { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - gd54xx_write(addr+2, val >> 16, gd54xx); - gd54xx_write(addr+3, val >> 24, gd54xx); - return; - } - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - - if (svga->writemode < 4) - svga_writel_linear(addr, val, svga); - else { - svga_write_linear(addr, val, svga); - svga_write_linear(addr+1, val >> 8, svga); - svga_write_linear(addr+2, val >> 16, svga); - svga_write_linear(addr+3, val >> 24, svga); - } -} - - -/* This adds write modes 4 and 5 to SVGA. */ -static void -gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr) -{ - uint32_t i, j; - - switch (svga->writemode) { - case 4: - if (svga->gdcreg[0xb] & 0x10) { - addr <<= 2; - - for (i = 0; i < 8; i++) { - if (val & svga->seqregs[2] & (0x80 >> i)) { - svga->vram[addr + (i << 1)] = svga->gdcreg[1]; - svga->vram[addr + (i << 1) + 1] = svga->gdcreg[0x11]; - } - } - } else { - addr <<= 1; - - for (i = 0; i < 8; i++) { - if (val & svga->seqregs[2] & (0x80 >> i)) - svga->vram[addr + i] = svga->gdcreg[1]; - } - } - break; - - case 5: - if (svga->gdcreg[0xb] & 0x10) { - addr <<= 2; - - for (i = 0; i < 8; i++) { - j = (0x80 >> i); - if (svga->seqregs[2] & j) { - svga->vram[addr + (i << 1)] = (val & j) ? - svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + (i << 1) + 1] = (val & j) ? - svga->gdcreg[0x11] : svga->gdcreg[0x10]; - } - } - } else { - addr <<= 1; - - for (i = 0; i < 8; i++) { - j = (0x80 >> i); - if (svga->seqregs[2] & j) - svga->vram[addr + i] = (val & j) ? svga->gdcreg[1] : svga->gdcreg[0]; - } - } - break; - } - - svga->changedvram[addr >> 12] = changeframecount; -} - - -static uint8_t -gd54xx_get_aperture(uint32_t addr) -{ - uint32_t ap = addr >> 22; - return (uint8_t) (ap & 0x03); -} - - -static uint8_t -gd54xx_readb_linear(uint32_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - addr &= 0x003fffff; /* 4 MB mask */ - - switch (ap) { - case 0: - default: - break; - case 1: - /* 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2 */ - addr ^= 0x00000001; - break; - case 2: - /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ - addr ^= 0x00000003; - break; - case 3: - return 0xff; - } - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) - return gd543x_mmio_read(addr & 0x000000ff, gd54xx); - } - - return svga_read_linear(addr, p); -} - - -static uint16_t -gd54xx_readw_linear(uint32_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - uint16_t temp, temp2; - - addr &= 0x003fffff; /* 4 MB mask */ - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - if (ap == 2) - addr ^= 0x00000002; - - temp = gd543x_mmio_readw(addr & 0x000000ff, gd54xx); - - switch(ap) { - case 0: - default: - return temp; - case 1: - case 2: - temp2 = temp >> 8; - temp2 |= ((temp & 0xff) << 8); - return temp; - case 3: - return 0xffff; - } - } - } - - switch (ap) { - case 0: - default: - return svga_readw_linear(addr, p); - case 2: - /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ - addr ^= 0x00000002; - case 1: - temp = svga_readb_linear(addr + 1, p); - temp |= (svga_readb_linear(addr, p) << 8); - - if (svga->fast) - cycles -= video_timing_read_w; - - return temp; - case 3: - return 0xffff; - } -} - - -static uint32_t -gd54xx_readl_linear(uint32_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - uint32_t temp, temp2; - - addr &= 0x003fffff; /* 4 MB mask */ - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - temp = gd543x_mmio_readl(addr & 0x000000ff, gd54xx); - - switch(ap) { - case 0: - default: - return temp; - case 1: - temp2 = temp >> 24; - temp2 |= ((temp >> 16) & 0xff) << 8; - temp2 |= ((temp >> 8) & 0xff) << 16; - temp2 |= (temp & 0xff) << 24; - - return temp2; - case 2: - temp2 = (temp >> 8) & 0xff; - temp2 |= (temp & 0xff) << 8; - temp2 = ((temp >> 24) & 0xff) << 16; - temp2 = ((temp >> 16) & 0xff) << 24; - - return temp2; - case 3: - return 0xffffffff; - } - } - } - - switch (ap) { - case 0: - default: - return svga_readw_linear(addr, p); - case 1: - temp = svga_readb_linear(addr + 1, p); - temp |= (svga_readb_linear(addr, p) << 8); - temp |= (svga_readb_linear(addr + 3, p) << 16); - temp |= (svga_readb_linear(addr + 2, p) << 24); - - if (svga->fast) - cycles -= video_timing_read_l; - - return temp; - case 2: - temp = svga_readb_linear(addr + 3, p); - temp |= (svga_readb_linear(addr + 2, p) << 8); - temp |= (svga_readb_linear(addr + 1, p) << 16); - temp |= (svga_readb_linear(addr, p) << 24); - - if (svga->fast) - cycles -= video_timing_read_l; - - return temp; - case 3: - return 0xffffffff; - } -} - - -static void -gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - addr &= 0x003fffff; /* 4 MB mask */ - - switch (ap) { - case 0: - default: - break; - case 1: - /* 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2 */ - addr ^= 0x00000001; - break; - case 2: - /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ - addr ^= 0x00000003; - break; - case 3: - return; - } - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) - gd543x_mmio_write(addr & 0x000000ff, val, gd54xx); - } - - if (gd54xx->blt.sys_tx) { - if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { - gd54xx->blt.sys_buf &= ~(0xff << (gd54xx->blt.sys_cnt * 8)); - gd54xx->blt.sys_buf |= (val << (gd54xx->blt.sys_cnt * 8)); - gd54xx->blt.sys_cnt++; - if(gd54xx->blt.sys_cnt >= 4) { - gd54xx_blit_dword(gd54xx, svga); - gd54xx->blt.sys_cnt = 0; - } - } - return; - } - - svga_write_linear(addr, val, svga); -} - - -static void -gd54xx_writew_linear(uint32_t addr, uint16_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - uint16_t temp; - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - switch(ap) { - case 0: - default: - gd543x_mmio_writew(addr & 0x000000ff, val, gd54xx); - return; - case 2: - addr ^= 0x00000002; - case 1: - temp = (val >> 8); - temp |= ((val & 0xff) << 8); - gd543x_mmio_writew(addr & 0x000000ff, temp, gd54xx); - case 3: - return; - } - } - } - - if (gd54xx->blt.sys_tx) { - gd54xx_writeb_linear(addr, val, svga); - gd54xx_writeb_linear(addr+1, val >> 8, svga); - return; - } - - addr &= 0x003fffff; /* 4 MB mask */ - - if (svga->writemode < 4) { - switch(ap) { - case 0: - default: - svga_writew_linear(addr, val, svga); - return; - case 2: - addr ^= 0x00000002; - case 1: - svga_writeb_linear(addr + 1, val & 0xff, svga); - svga_writeb_linear(addr, val >> 8, svga); - - if (svga->fast) - cycles -= video_timing_write_w; - case 3: - return; - } - } else { - switch(ap) { - case 0: - default: - svga_write_linear(addr, val & 0xff, svga); - svga_write_linear(addr + 1, val >> 8, svga); - return; - case 2: - addr ^= 0x00000002; - case 1: - svga_write_linear(addr + 1, val & 0xff, svga); - svga_write_linear(addr, val >> 8, svga); - case 3: - return; - } - } -} - - -static void -gd54xx_writel_linear(uint32_t addr, uint32_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - uint32_t temp; - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - switch(ap) { - case 0: - default: - gd543x_mmio_writel(addr & 0x000000ff, val, gd54xx); - return; - case 2: - temp = (val >> 24); - temp |= ((val >> 16) & 0xff) << 8; - temp |= ((val >> 8) & 0xff) << 16; - temp |= (val & 0xff) << 24; - gd543x_mmio_writel(addr & 0x000000ff, temp, gd54xx); - return; - case 1: - temp = ((val >> 8) & 0xff); - temp |= (val & 0xff) << 8; - temp |= (val >> 24) << 16; - temp |= ((val >> 16) & 0xff) << 24; - gd543x_mmio_writel(addr & 0x000000ff, temp, gd54xx); - return; - case 3: - return; - } - } - } - - if (gd54xx->blt.sys_tx) { - gd54xx_writeb_linear(addr, val, svga); - gd54xx_writeb_linear(addr+1, val >> 8, svga); - gd54xx_writeb_linear(addr+2, val >> 16, svga); - gd54xx_writeb_linear(addr+3, val >> 24, svga); - return; - } - - addr &= 0x003fffff; /* 4 MB mask */ - - if (svga->writemode < 4) { - switch(ap) { - case 0: - default: - svga_writel_linear(addr, val, svga); - return; - case 1: - svga_writeb_linear(addr + 1, val & 0xff, svga); - svga_writeb_linear(addr, val >> 8, svga); - svga_writeb_linear(addr + 3, val >> 16, svga); - svga_writeb_linear(addr + 2, val >> 24, svga); - return; - case 2: - svga_writeb_linear(addr + 3, val & 0xff, svga); - svga_writeb_linear(addr + 2, val >> 8, svga); - svga_writeb_linear(addr + 1, val >> 16, svga); - svga_writeb_linear(addr, val >> 24, svga); - case 3: - return; - } - - if (svga->fast) - cycles -= video_timing_write_l; - } else { - switch(ap) { - case 0: - default: - svga_write_linear(addr, val & 0xff, svga); - svga_write_linear(addr+1, val >> 8, svga); - svga_write_linear(addr+2, val >> 16, svga); - svga_write_linear(addr+3, val >> 24, svga); - return; - case 1: - svga_write_linear(addr + 1, val & 0xff, svga); - svga_write_linear(addr, val >> 8, svga); - svga_write_linear(addr + 3, val >> 16, svga); - svga_write_linear(addr + 2, val >> 24, svga); - return; - case 2: - svga_write_linear(addr + 3, val & 0xff, svga); - svga_write_linear(addr + 2, val >> 8, svga); - svga_write_linear(addr + 1, val >> 16, svga); - svga_write_linear(addr, val >> 24, svga); - case 3: - return; - } - } -} - - -static uint8_t -gd54xx_read(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - return svga_read_linear(addr, svga); -} - - -static uint16_t -gd54xx_readw(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - return svga_readw_linear(addr, svga); -} - - -static uint32_t -gd54xx_readl(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - return svga_readl_linear(addr, svga); -} - - -static int -gd543x_do_mmio(svga_t *svga, uint32_t addr) -{ - if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) - return 1; - else - return ((addr & ~0xff) == 0xb8000); -} - - -static void -gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) { - switch (addr & 0xff) { - case 0x00: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xffffff00) | val; - else - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00) | val; - break; - case 0x01: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xffff00ff) | (val << 8); - else - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ff) | (val << 8); - break; - case 0x02: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00ffff) | (val << 16); - break; - case 0x03: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ffffff) | (val << 24); - break; - - case 0x04: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xffffff00) | val; - else - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00) | val; - break; - case 0x05: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xffff00ff) | (val << 8); - else - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ff) | (val << 8); - break; - case 0x06: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00ffff) | (val << 16); - break; - case 0x07: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ffffff) | (val << 24); - break; - - case 0x08: - gd54xx->blt.width = (gd54xx->blt.width & 0xff00) | val; - break; - case 0x09: - gd54xx->blt.width = (gd54xx->blt.width & 0x00ff) | (val << 8); - if (gd54xx_is_5434(svga)) - gd54xx->blt.width &= 0x1fff; - else - gd54xx->blt.width &= 0x07ff; - break; - case 0x0a: - gd54xx->blt.height = (gd54xx->blt.height & 0xff00) | val; - break; - case 0x0b: - gd54xx->blt.height = (gd54xx->blt.height & 0x00ff) | (val << 8); - gd54xx->blt.height &= 0x03ff; - break; - case 0x0c: - gd54xx->blt.dst_pitch = (gd54xx->blt.dst_pitch & 0xff00) | val; - break; - case 0x0d: - gd54xx->blt.dst_pitch = (gd54xx->blt.dst_pitch & 0x00ff) | (val << 8); - break; - case 0x0e: - gd54xx->blt.src_pitch = (gd54xx->blt.src_pitch & 0xff00) | val; - break; - case 0x0f: - gd54xx->blt.src_pitch = (gd54xx->blt.src_pitch & 0x00ff) | (val << 8); - break; - - case 0x10: - gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0xffff00) | val; - break; - case 0x11: - gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0xff00ff) | (val << 8); - break; - case 0x12: - gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0x00ffff) | (val << 16); - if (gd54xx_is_5434(svga)) - gd54xx->blt.dst_addr &= 0x3fffff; - else - gd54xx->blt.dst_addr &= 0x1fffff; - - if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) && (gd54xx->blt.status & CIRRUS_BLT_AUTOSTART)) { - if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { - gd54xx->blt.sys_tx = 1; - gd54xx->blt.sys_cnt = 0; - gd54xx->blt.sys_buf = 0; - gd54xx->blt.pixel_cnt = gd54xx->blt.scan_cnt = 0; - gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; - } else - gd54xx_start_blit(0, -1, gd54xx, svga); - } - break; - - case 0x14: - gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0xffff00) | val; - break; - case 0x15: - gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0xff00ff) | (val << 8); - break; - case 0x16: - gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0x00ffff) | (val << 16); - if (gd54xx_is_5434(svga)) - gd54xx->blt.src_addr &= 0x3fffff; - else - gd54xx->blt.src_addr &= 0x1fffff; - break; - - case 0x17: - gd54xx->blt.mask = val; - break; - case 0x18: - gd54xx->blt.mode = val; - break; - - case 0x1a: - gd54xx->blt.rop = val; - break; - - case 0x1b: - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - gd54xx->blt.modeext = val; - break; - - case 0x1c: - gd54xx->blt.trans_col = (gd54xx->blt.trans_col & 0xff00) | val; - break; - - case 0x1d: - gd54xx->blt.trans_col = (gd54xx->blt.trans_col & 0x00ff) | (val << 8); - break; - - case 0x20: - gd54xx->blt.trans_mask = (gd54xx->blt.trans_mask & 0xff00) | val; - break; - - case 0x21: - gd54xx->blt.trans_mask = (gd54xx->blt.trans_mask & 0x00ff) | (val << 8); - break; - - case 0x40: - gd54xx->blt.status = val; - if (gd54xx->blt.status & CIRRUS_BLT_START) { - if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { - gd54xx->blt.sys_tx = 1; - gd54xx->blt.sys_cnt = 0; - gd54xx->blt.sys_buf = 0; - gd54xx->blt.pixel_cnt = gd54xx->blt.scan_cnt = 0; - gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; - } else - gd54xx_start_blit(0, -1, gd54xx, svga); - } - break; - } - } else if (gd54xx->mmio_vram_overlap) - gd54xx_write(addr, val, gd54xx); -} - - -static void -gd543x_mmio_writew(uint32_t addr, uint16_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) { - gd543x_mmio_write(addr, val & 0xff, gd54xx); - gd543x_mmio_write(addr+1, val >> 8, gd54xx); - } else if (gd54xx->mmio_vram_overlap) { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - } -} - - -static void -gd543x_mmio_writel(uint32_t addr, uint32_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) { - gd543x_mmio_write(addr, val & 0xff, gd54xx); - gd543x_mmio_write(addr+1, val >> 8, gd54xx); - gd543x_mmio_write(addr+2, val >> 16, gd54xx); - gd543x_mmio_write(addr+3, val >> 24, gd54xx); - } else if (gd54xx->mmio_vram_overlap) { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - gd54xx_write(addr+2, val >> 16, gd54xx); - gd54xx_write(addr+3, val >> 24, gd54xx); - } -} - - -static uint8_t -gd543x_mmio_read(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) { - switch (addr & 0xff) { - case 0x40: /*BLT status*/ - return 0; - } - return 0xff; /*All other registers read-only*/ - } - else if (gd54xx->mmio_vram_overlap) - return gd54xx_read(addr, gd54xx); - return 0xff; -} - - -static uint16_t -gd543x_mmio_readw(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) - return gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr+1, gd54xx) << 8); - else if (gd54xx->mmio_vram_overlap) - return gd54xx_read(addr, gd54xx) | (gd54xx_read(addr+1, gd54xx) << 8); - return 0xffff; -} - - -static uint32_t -gd543x_mmio_readl(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) - return gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr+1, gd54xx) << 8) | (gd543x_mmio_read(addr+2, gd54xx) << 16) | (gd543x_mmio_read(addr+3, gd54xx) << 24); - else if (gd54xx->mmio_vram_overlap) - return gd54xx_read(addr, gd54xx) | (gd54xx_read(addr+1, gd54xx) << 8) | (gd54xx_read(addr+2, gd54xx) << 16) | (gd54xx_read(addr+3, gd54xx) << 24); - return 0xffffffff; -} - - -static void -gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) -{ - int blt_mask = 0; - int x_max = 0; - - int shift = 0, last_x = 0; - - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - blt_mask = gd54xx->blt.mask & 7; - x_max = 8; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - blt_mask = gd54xx->blt.mask & 7; - x_max = 16; - blt_mask *= 2; - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - blt_mask = (gd54xx->blt.mask & 0x1f); - x_max = 24; - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - blt_mask = gd54xx->blt.mask & 7; - x_max = 32; - blt_mask *= 4; - break; - } - - last_x = (x_max >> 3) - 1; - - if (count == -1) { - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; - gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; - gd54xx->blt.width_backup = gd54xx->blt.width; - gd54xx->blt.height_internal = gd54xx->blt.height; - gd54xx->blt.x_count = 0; - if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) == (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) - gd54xx->blt.y_count = gd54xx->blt.src_addr & 7; - else - gd54xx->blt.y_count = 0; - - if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) == (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) { - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_set_handler(&svga->mapping, NULL, NULL, NULL, NULL, gd54xx_blt_write_w, gd54xx_blt_write_l); - mem_mapping_set_p(&svga->mapping, gd54xx); - } else { - mem_mapping_set_handler(&gd54xx->linear_mapping, NULL, NULL, NULL, NULL, gd54xx_blt_write_w, gd54xx_blt_write_l); - mem_mapping_set_p(&gd54xx->linear_mapping, gd54xx); - } - gd543x_recalc_mapping(gd54xx); - return; - } else if (gd54xx->blt.mode != CIRRUS_BLTMODE_MEMSYSSRC) { - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); - mem_mapping_set_p(&gd54xx->svga.mapping, gd54xx); - } else { - mem_mapping_set_handler(&gd54xx->linear_mapping, svga_readb_linear, svga_readw_linear, svga_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear); - mem_mapping_set_p(&gd54xx->linear_mapping, svga); - } - gd543x_recalc_mapping(gd54xx); - } - } else if (gd54xx->blt.height_internal == 0xffff) - return; - - while (count) { - uint8_t src = 0, dst; - int mask = 0; - - if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) { - if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY) - mask = (cpu_dat >> 31); - else - mask = cpu_dat & 0x80; - - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; - shift = 0; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - shift = (gd54xx->blt.x_count & 1); - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - shift = (gd54xx->blt.x_count % 3); - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - shift = (gd54xx->blt.x_count & 3); - break; - } - - src = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); - - if (shift == last_x) { - cpu_dat <<= 1; - count--; - } - } - } else { - switch (gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) { - case 0x00: - src = svga->vram[gd54xx->blt.src_addr & svga->vram_mask]; - gd54xx->blt.src_addr += ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -1 : 1); - mask = 1; - break; - case CIRRUS_BLTMODE_PATTERNCOPY: - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~7)) + (gd54xx->blt.y_count << 3) + (gd54xx->blt.x_count & 7)]; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~15)) + (gd54xx->blt.y_count << 4) + (gd54xx->blt.x_count & 15)]; - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~31)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count % 24)]; - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~31)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count & 31)]; - break; - } - mask = 1; - break; - case CIRRUS_BLTMODE_COLOREXPAND: - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> gd54xx->blt.x_count); - shift = 0; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count >> 1)); - shift = (gd54xx->blt.dst_addr & 1); - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count / 3)); - shift = (gd54xx->blt.dst_addr % 3); - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count >> 2)); - shift = (gd54xx->blt.dst_addr & 3); - break; - } - src = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); - break; - case CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND: - if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) { - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - shift = 0; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - shift = (gd54xx->blt.dst_addr & 1); - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - shift = (gd54xx->blt.dst_addr % 3); - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - shift = (gd54xx->blt.dst_addr & 3); - break; - } - src = (gd54xx->blt.fg_col >> (shift << 3)); - } else { - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> gd54xx->blt.x_count); - shift = 0; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count >> 1)); - shift = (gd54xx->blt.dst_addr & 1); - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count / 3)); - shift = (gd54xx->blt.dst_addr % 3); - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count >> 2)); - shift = (gd54xx->blt.dst_addr & 3); - break; - } - - src = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); - } - break; - } - count--; - } - dst = svga->vram[gd54xx->blt.dst_addr & svga->vram_mask]; - svga->changedvram[(gd54xx->blt.dst_addr & svga->vram_mask) >> 12] = changeframecount; - - switch (gd54xx->blt.rop) { - case 0x00: dst = 0; break; - case 0x05: dst = src & dst; break; - case 0x06: dst = dst; break; - case 0x09: dst = src & ~dst; break; - case 0x0b: dst = ~ dst; break; - case 0x0d: dst = src; break; - case 0x0e: dst = 0xff; break; - case 0x50: dst = ~ src & dst; break; - case 0x59: dst = src ^ dst; break; - case 0x6d: dst = src | dst; break; - case 0x90: dst = ~(src | dst); break; - case 0x95: dst = ~(src ^ dst); break; - case 0xad: dst = src | ~dst; break; - case 0xd0: dst = ~src; break; - case 0xd6: dst = ~src | dst; break; - case 0xda: dst = ~(src & dst); break; - } - - if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { - if ((gd54xx->blt.width_backup - gd54xx->blt.width) >= blt_mask && - !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && mask)) - svga->vram[gd54xx->blt.dst_addr & svga->vram_mask] = dst; - } else { - if ((gd54xx->blt.width_backup - gd54xx->blt.width) >= blt_mask && - !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !mask)) - svga->vram[gd54xx->blt.dst_addr & svga->vram_mask] = dst; - } - - gd54xx->blt.dst_addr += ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -1 : 1); - - gd54xx->blt.x_count++; - - if (gd54xx->blt.x_count == x_max) { - gd54xx->blt.x_count = 0; - if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) == CIRRUS_BLTMODE_COLOREXPAND) - gd54xx->blt.src_addr++; - } - - gd54xx->blt.width--; - - if (gd54xx->blt.width == 0xffff) { - gd54xx->blt.width = gd54xx->blt.width_backup; - - gd54xx->blt.dst_addr = gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr_backup + ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -gd54xx->blt.dst_pitch : gd54xx->blt.dst_pitch); - - switch (gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) { - case 0x00: - gd54xx->blt.src_addr = gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr_backup + ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -gd54xx->blt.src_pitch : gd54xx->blt.src_pitch); - break; - case CIRRUS_BLTMODE_COLOREXPAND: - if (gd54xx->blt.x_count != 0) - gd54xx->blt.src_addr++; - break; - } - - gd54xx->blt.x_count = 0; - if (gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) - gd54xx->blt.y_count = (gd54xx->blt.y_count - 1) & 7; - else - gd54xx->blt.y_count = (gd54xx->blt.y_count + 1) & 7; - - gd54xx->blt.height_internal--; - if (gd54xx->blt.height_internal == 0xffff) { - if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) { - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); - mem_mapping_set_p(&svga->mapping, gd54xx); - } else { - mem_mapping_set_handler(&gd54xx->linear_mapping, svga_readb_linear, svga_readw_linear, svga_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear); - mem_mapping_set_p(&gd54xx->linear_mapping, svga); - } - gd543x_recalc_mapping(gd54xx); - } - return; - } - - if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) - return; - } - } -} - - -static uint8_t -cl_pci_read(int func, int addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) - return 0; - - switch (addr) { - case 0x00: return 0x13; /*Cirrus Logic*/ - case 0x01: return 0x10; - - case 0x02: - return svga->crtc[0x27]; - case 0x03: return 0x00; - - case PCI_REG_COMMAND: - return gd54xx->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - - // case 0x07: return 0 << 1; /*Fast DEVSEL timing*/ - case 0x07: return 0x02; /*Fast DEVSEL timing*/ - - case 0x08: return gd54xx->rev; /*Revision ID*/ - case 0x09: return 0x00; /*Programming interface*/ - - case 0x0a: return 0x00; /*Supports VGA interface*/ - case 0x0b: return 0x03; - - case 0x10: return 0x08; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: return 0x00; - case 0x13: return gd54xx->lfb_base >> 24; - - case 0x30: return (gd54xx->pci_regs[0x30] & 0x01); /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return gd54xx->pci_regs[0x32]; - case 0x33: return gd54xx->pci_regs[0x33]; - - case 0x3c: return gd54xx->int_line; - case 0x3d: return PCI_INTA; - } - return 0; -} - - -static void -cl_pci_write(int func, int addr, uint8_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) - return; - - switch (addr) { - case PCI_REG_COMMAND: - gd54xx->pci_regs[PCI_REG_COMMAND] = val & 0x23; - io_removehandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - if (val & PCI_COMMAND_IO) - io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - gd543x_recalc_mapping(gd54xx); - break; - - case 0x13: - gd54xx->lfb_base = val << 24; - gd543x_recalc_mapping(gd54xx); - break; - - case 0x30: case 0x32: case 0x33: - gd54xx->pci_regs[addr] = val; - if (gd54xx->pci_regs[0x30] & 0x01) { - uint32_t addr = (gd54xx->pci_regs[0x32] << 16) | (gd54xx->pci_regs[0x33] << 24); - mem_mapping_set_addr(&gd54xx->bios_rom.mapping, addr, 0x8000); - } else - mem_mapping_disable(&gd54xx->bios_rom.mapping); - return; - - case 0x3c: - gd54xx->int_line = val; - return; - } -} - - -static void -*gd54xx_init(const device_t *info) -{ - gd54xx_t *gd54xx = malloc(sizeof(gd54xx_t)); - svga_t *svga = &gd54xx->svga; - int id = info->local & 0xff; - wchar_t *romfn = NULL; - memset(gd54xx, 0, sizeof(gd54xx_t)); - - gd54xx->pci = !!(info->flags & DEVICE_PCI); - gd54xx->vlb = !!(info->flags & DEVICE_VLB); - - gd54xx->rev = 0; - gd54xx->has_bios = 1; - switch (id) { - case CIRRUS_ID_CLGD5426: - romfn = BIOS_GD5426_PATH; - break; - - case CIRRUS_ID_CLGD5428: - if (gd54xx->vlb) - romfn = BIOS_GD5428_PATH; - else - romfn = BIOS_GD5428_ISA_PATH; - break; - - case CIRRUS_ID_CLGD5429: - romfn = BIOS_GD5429_PATH; - break; - - case CIRRUS_ID_CLGD5434: - romfn = BIOS_GD5434_PATH; - break; - - case CIRRUS_ID_CLGD5436: - romfn = BIOS_GD5436_PATH; - break; - - case CIRRUS_ID_CLGD5430: - if (info->local & 0x400) { - /* CL-GD 5440 */ - gd54xx->rev = 0x47; - if (info->local & 0x200) { - romfn = NULL; - gd54xx->has_bios = 0; - } else - romfn = BIOS_GD5440_PATH; - } else { - /* CL-GD 5430 */ - if (gd54xx->pci) - romfn = BIOS_GD5430_PCI_PATH; - else - romfn = BIOS_GD5430_VLB_PATH; - } - break; - - case CIRRUS_ID_CLGD5446: - if (info->local & 0x100) - romfn = BIOS_GD5446_STB_PATH; - else - romfn = BIOS_GD5446_PATH; - break; - - case CIRRUS_ID_CLGD5480: - romfn = BIOS_GD5480_PATH; - break; - } - - gd54xx->vram_size = device_get_config_int("memory"); - gd54xx->vram_mask = (gd54xx->vram_size << 20) - 1; - - if (romfn) - rom_init(&gd54xx->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - svga_init(&gd54xx->svga, gd54xx, gd54xx->vram_size << 20, - gd54xx_recalctimings, gd54xx_in, gd54xx_out, - gd54xx_hwcursor_draw, NULL); - svga_set_ven_write(&gd54xx->svga, gd54xx_write_modes45); - - mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); - mem_mapping_set_p(&svga->mapping, gd54xx); - - mem_mapping_add(&gd54xx->mmio_mapping, 0, 0, gd543x_mmio_read, gd543x_mmio_readw, gd543x_mmio_readl, gd543x_mmio_write, gd543x_mmio_writew, gd543x_mmio_writel, NULL, 0, gd54xx); - mem_mapping_add(&gd54xx->linear_mapping, 0, 0, gd54xx_readb_linear, gd54xx_readw_linear, gd54xx_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear, NULL, 0, svga); - - io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - - svga->hwcursor.yoff = 32; - svga->hwcursor.xoff = 0; - - gd54xx->vclk_n[0] = 0x4a; - gd54xx->vclk_d[0] = 0x2b; - gd54xx->vclk_n[1] = 0x5b; - gd54xx->vclk_d[1] = 0x2f; - - gd54xx->bank[1] = 0x8000; - - if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430) - pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx); - - gd54xx->pci_regs[PCI_REG_COMMAND] = 7; - - gd54xx->pci_regs[0x30] = 0x00; - gd54xx->pci_regs[0x32] = 0x0c; - gd54xx->pci_regs[0x33] = 0x00; - - svga->crtc[0x27] = id; - - return gd54xx; -} - -static int -gd5426_available(void) -{ - return rom_present(BIOS_GD5426_PATH); -} - -static int -gd5428_available(void) -{ - return rom_present(BIOS_GD5428_PATH); -} - -static int -gd5428_isa_available(void) -{ - return rom_present(BIOS_GD5428_ISA_PATH); -} - -static int -gd5429_available(void) -{ - return rom_present(BIOS_GD5429_PATH); -} - -static int -gd5430_vlb_available(void) -{ - return rom_present(BIOS_GD5430_VLB_PATH); -} - -static int -gd5430_pci_available(void) -{ - return rom_present(BIOS_GD5430_PCI_PATH); -} - -static int -gd5434_available(void) -{ - return rom_present(BIOS_GD5434_PATH); -} - -static int -gd5436_available(void) -{ - return rom_present(BIOS_GD5436_PATH); -} - -static int -gd5440_available(void) -{ - return rom_present(BIOS_GD5440_PATH); -} - -static int -gd5446_available(void) -{ - return rom_present(BIOS_GD5446_PATH); -} - -static int -gd5446_stb_available(void) -{ - return rom_present(BIOS_GD5446_STB_PATH); -} - -static int -gd5480_available(void) -{ - return rom_present(BIOS_GD5480_PATH); -} - -void -gd54xx_close(void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - svga_close(&gd54xx->svga); - - free(gd54xx); -} - - -void -gd54xx_speed_changed(void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - svga_recalctimings(&gd54xx->svga); -} - - -void -gd54xx_force_redraw(void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - gd54xx->svga.fullchange = changeframecount; -} - - -static const device_config_t gd5428_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } -}; - -static const device_config_t gd5440_onboard_config[] = -{ - { - .name = "memory", - .description = "Video memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } -}; - -static const device_config_t gd5434_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } -}; - -const device_t gd5426_vlb_device = -{ - "Cirrus Logic CL-GD 5426 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5426, - gd54xx_init, - gd54xx_close, - NULL, - gd5426_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5428_isa_device = -{ - "Cirrus Logic CL-GD 5428 (ISA)", - DEVICE_AT | DEVICE_ISA, - CIRRUS_ID_CLGD5428, - gd54xx_init, - gd54xx_close, - NULL, - gd5428_isa_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5428_vlb_device = -{ - "Cirrus Logic CL-GD 5428 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5428, - gd54xx_init, - gd54xx_close, - NULL, - gd5428_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5429_isa_device = -{ - "Cirrus Logic CL-GD 5429 (ISA)", - DEVICE_AT | DEVICE_ISA, - CIRRUS_ID_CLGD5429, - gd54xx_init, - gd54xx_close, - NULL, - gd5429_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5429_vlb_device = -{ - "Cirrus Logic CL-GD 5429 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5429, - gd54xx_init, - gd54xx_close, - NULL, - gd5429_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5430_vlb_device = -{ - "Cirrus Logic CL-GD 5430 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5430, - gd54xx_init, - gd54xx_close, - NULL, - gd5430_vlb_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5430_pci_device = -{ - "Cirrus Logic CL-GD 5430 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5430, - gd54xx_init, - gd54xx_close, - NULL, - gd5430_pci_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5434_isa_device = -{ - "Cirrus Logic CL-GD 5434 (ISA)", - DEVICE_AT | DEVICE_ISA, - CIRRUS_ID_CLGD5434, - gd54xx_init, - gd54xx_close, - NULL, - gd5434_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5434_vlb_device = -{ - "Cirrus Logic CL-GD 5434 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5434, - gd54xx_init, - gd54xx_close, - NULL, - gd5434_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5434_pci_device = -{ - "Cirrus Logic CL-GD 5434 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5434, - gd54xx_init, - gd54xx_close, - NULL, - gd5434_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5436_pci_device = -{ - "Cirrus Logic CL-GD 5436 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5436, - gd54xx_init, - gd54xx_close, - NULL, - gd5436_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5440_onboard_pci_device = -{ - "Cirrus Logic CL-GD 5440 (On-Board PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5440 | 0x600, - gd54xx_init, - gd54xx_close, - NULL, - NULL, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5440_onboard_config -}; - -const device_t gd5440_pci_device = -{ - "Cirrus Logic CL-GD 5440 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5440 | 0x400, - gd54xx_init, - gd54xx_close, - NULL, - gd5440_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5446_pci_device = -{ - "Cirrus Logic CL-GD 5446 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5446, - gd54xx_init, - gd54xx_close, - NULL, - gd5446_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5446_stb_pci_device = -{ - "STB Nitro 64V (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5446 | 0x100, - gd54xx_init, - gd54xx_close, - NULL, - gd5446_stb_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5480_pci_device = -{ - "Cirrus Logic CL-GD 5480 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5480, - gd54xx_init, - gd54xx_close, - NULL, - gd5480_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; diff --git a/backup code/video - Cópia/vid_cl54xx.c b/backup code/video - Cópia/vid_cl54xx.c deleted file mode 100644 index 85c518fdd..000000000 --- a/backup code/video - Cópia/vid_cl54xx.c +++ /dev/null @@ -1,2691 +0,0 @@ -/* - * 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 select Cirrus Logic cards (CL-GD 5428, - * CL-GD 5429, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). - * - * Version: @(#)vid_cl_54xx.c 1.0.19 2018/05/08 - * - * Authors: Sarah Walker, - * Barry Rodewald, - * TheCollector1995, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2018 Barry Rodewald - * Copyright 2016-2018 TheCollector1995. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_svga_render.h" -#include "vid_cl54xx.h" - -#define BIOS_GD5426_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin" -#define BIOS_GD5428_ISA_PATH L"roms/video/cirruslogic/5428.bin" -#define BIOS_GD5428_PATH L"roms/video/cirruslogic/vlbusjapan.BIN" -#define BIOS_GD5429_PATH L"roms/video/cirruslogic/5429.vbi" -#define BIOS_GD5430_VLB_PATH L"roms/video/cirruslogic/diamondvlbus.bin" -#define BIOS_GD5430_PCI_PATH L"roms/video/cirruslogic/pci.bin" -#define BIOS_GD5434_PATH L"roms/video/cirruslogic/gd5434.bin" -#define BIOS_GD5436_PATH L"roms/video/cirruslogic/5436.vbi" -#define BIOS_GD5440_PATH L"roms/video/cirruslogic/BIOS.BIN" -#define BIOS_GD5446_PATH L"roms/video/cirruslogic/5446BV.VBI" -#define BIOS_GD5446_STB_PATH L"roms/video/cirruslogic/stb nitro64v.BIN" -#define BIOS_GD5480_PATH L"roms/video/cirruslogic/clgd5480.rom" - -#define CIRRUS_ID_CLGD5426 0x90 -#define CIRRUS_ID_CLGD5428 0x98 -#define CIRRUS_ID_CLGD5429 0x9c -#define CIRRUS_ID_CLGD5430 0xa0 -#define CIRRUS_ID_CLGD5434 0xa8 -#define CIRRUS_ID_CLGD5436 0xac -#define CIRRUS_ID_CLGD5440 0xa0 /* Yes, the 5440 has the same ID as the 5430. */ -#define CIRRUS_ID_CLGD5446 0xb8 -#define CIRRUS_ID_CLGD5480 0xbc - -/* sequencer 0x07 */ -#define CIRRUS_SR7_BPP_VGA 0x00 -#define CIRRUS_SR7_BPP_SVGA 0x01 -#define CIRRUS_SR7_BPP_MASK 0x0e -#define CIRRUS_SR7_BPP_8 0x00 -#define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02 -#define CIRRUS_SR7_BPP_24 0x04 -#define CIRRUS_SR7_BPP_16 0x06 -#define CIRRUS_SR7_BPP_32 0x08 -#define CIRRUS_SR7_ISAADDR_MASK 0xe0 - -/* sequencer 0x12 */ -#define CIRRUS_CURSOR_SHOW 0x01 -#define CIRRUS_CURSOR_HIDDENPEL 0x02 -#define CIRRUS_CURSOR_LARGE 0x04 /* 64x64 if set, 32x32 if clear */ - -// sequencer 0x17 -#define CIRRUS_BUSTYPE_VLBFAST 0x10 -#define CIRRUS_BUSTYPE_PCI 0x20 -#define CIRRUS_BUSTYPE_VLBSLOW 0x30 -#define CIRRUS_BUSTYPE_ISA 0x38 -#define CIRRUS_MMIO_ENABLE 0x04 -#define CIRRUS_MMIO_USE_PCIADDR 0x40 /* 0xb8000 if cleared. */ -#define CIRRUS_MEMSIZEEXT_DOUBLE 0x80 - -// control 0x0b -#define CIRRUS_BANKING_DUAL 0x01 -#define CIRRUS_BANKING_GRANULARITY_16K 0x20 /* set:16k, clear:4k */ - -/* control 0x30 */ -#define CIRRUS_BLTMODE_BACKWARDS 0x01 -#define CIRRUS_BLTMODE_MEMSYSDEST 0x02 -#define CIRRUS_BLTMODE_MEMSYSSRC 0x04 -#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08 -#define CIRRUS_BLTMODE_PATTERNCOPY 0x40 -#define CIRRUS_BLTMODE_COLOREXPAND 0x80 -#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30 -#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00 -#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10 -#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20 -#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30 - -// control 0x31 -#define CIRRUS_BLT_BUSY 0x01 -#define CIRRUS_BLT_START 0x02 -#define CIRRUS_BLT_RESET 0x04 -#define CIRRUS_BLT_FIFOUSED 0x10 -#define CIRRUS_BLT_AUTOSTART 0x80 - -// control 0x33 -#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04 -#define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02 -#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01 - -#define CL_GD5429_SYSTEM_BUS_VESA 5 -#define CL_GD5429_SYSTEM_BUS_ISA 7 - -#define CL_GD543X_SYSTEM_BUS_PCI 4 -#define CL_GD543X_SYSTEM_BUS_VESA 6 -#define CL_GD543X_SYSTEM_BUS_ISA 7 - -typedef struct gd54xx_t -{ - mem_mapping_t mmio_mapping; - mem_mapping_t linear_mapping; - - svga_t svga; - - int has_bios, rev; - rom_t bios_rom; - - uint32_t vram_size; - uint32_t vram_mask; - - uint8_t vclk_n[4]; - uint8_t vclk_d[4]; - uint32_t bank[2]; - - struct { - uint8_t state; - int ctrl; - } ramdac; - - struct { - uint32_t fg_col, bg_col; - uint16_t width, height; - uint16_t dst_pitch, src_pitch; - uint32_t dst_addr, src_addr; - uint8_t mask, mode, rop; - uint8_t modeext; - uint8_t status; - uint16_t trans_col, trans_mask; - - uint32_t dst_addr_backup, src_addr_backup; - uint16_t width_backup, height_internal; - - int x_count, y_count; - int sys_tx; - uint8_t sys_cnt; - uint32_t sys_buf; - uint16_t pixel_cnt; - uint16_t scan_cnt; - } blt; - - int pci, vlb; - - uint8_t pci_regs[256]; - uint8_t int_line; - - int card; - - uint32_t lfb_base; - - int mmio_vram_overlap; - - uint32_t extpallook[256]; - PALETTE extpal; -} gd54xx_t; - -static void -gd543x_mmio_write(uint32_t addr, uint8_t val, void *p); -static void -gd543x_mmio_writew(uint32_t addr, uint16_t val, void *p); -static void -gd543x_mmio_writel(uint32_t addr, uint32_t val, void *p); -static uint8_t -gd543x_mmio_read(uint32_t addr, void *p); -static uint16_t -gd543x_mmio_readw(uint32_t addr, void *p); -static uint32_t -gd543x_mmio_readl(uint32_t addr, void *p); - -static void -gd54xx_recalc_banking(gd54xx_t *gd54xx); - -static void -gd543x_recalc_mapping(gd54xx_t *gd54xx); - -static void -gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga); - - -/* Returns 1 if the card is a 5434, 5436/46, or 5480. */ -static int -gd54xx_is_5434(svga_t *svga) -{ - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) - return 1; - else - return 0; -} - - -static void -gd54xx_out(uint16_t addr, uint8_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - uint8_t old; - int c; - uint8_t o; - uint32_t o32; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) { - case 0x3c0: - case 0x3c1: - if (!svga->attrff) { - svga->attraddr = val & 31; - if ((val & 0x20) != svga->attr_palette_enable) { - svga->fullchange = 3; - svga->attr_palette_enable = val & 0x20; - svga_recalctimings(svga); - } - } else { - o = svga->attrregs[svga->attraddr & 31]; - svga->attrregs[svga->attraddr & 31] = val; - if (svga->attraddr < 16) - svga->fullchange = changeframecount; - if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { - for (c = 0; c < 16; c++) { - if (svga->attrregs[0x10] & 0x80) svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); - else svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); - } - } - /* Recalculate timings on change of attribute register 0x11 (overscan border color) too. */ - if (svga->attraddr == 0x10) { - if (o != val) - svga_recalctimings(svga); - } else if (svga->attraddr == 0x11) { - if (!(svga->seqregs[0x12] & 0x80)) { - svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; - if (o != val) svga_recalctimings(svga); - } - } else if (svga->attraddr == 0x12) { - if ((val & 0xf) != svga->plane_mask) - svga->fullchange = changeframecount; - svga->plane_mask = val & 0xf; - } - } - svga->attrff ^= 1; - return; - case 0x3c4: - svga->seqaddr = val; - break; - case 0x3c5: - if (svga->seqaddr > 5) { - o = svga->seqregs[svga->seqaddr & 0x1f]; - svga->seqregs[svga->seqaddr & 0x1f] = val; - switch (svga->seqaddr & 0x1f) { - case 6: - val &= 0x17; - if (val == 0x12) - svga->seqregs[6] = 0x12; - else - svga->seqregs[6] = 0x0f; - break; - case 0x0b: case 0x0c: case 0x0d: case 0x0e: /* VCLK stuff */ - gd54xx->vclk_n[svga->seqaddr-0x0b] = val; - break; - case 0x1b: case 0x1c: case 0x1d: case 0x1e: /* VCLK stuff */ - gd54xx->vclk_d[svga->seqaddr-0x1b] = val; - break; - case 0x10: case 0x30: case 0x50: case 0x70: - case 0x90: case 0xb0: case 0xd0: case 0xf0: - svga->hwcursor.x = (val << 3) | (svga->seqaddr >> 5); - break; - case 0x11: case 0x31: case 0x51: case 0x71: - case 0x91: case 0xb1: case 0xd1: case 0xf1: - svga->hwcursor.y = (val << 3) | (svga->seqaddr >> 5); - break; - case 0x12: - if (val & 0x80) - svga->overscan_color = gd54xx->extpallook[2]; - else - svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; - svga_recalctimings(svga); - svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW; - svga->hwcursor.xsize = svga->hwcursor.ysize = (val & CIRRUS_CURSOR_LARGE) ? 64 : 32; - if (val & CIRRUS_CURSOR_LARGE) - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256)); - else - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3f) * 256)); - break; - case 0x13: - if (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3c) * 256)); - else - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3f) * 256)); - break; - case 0x07: - svga->set_reset_disabled = svga->seqregs[7] & 1; - case 0x17: - gd543x_recalc_mapping(gd54xx); - break; - } - return; - } - break; - case 0x3C6: - if (gd54xx->ramdac.state == 4) { - gd54xx->ramdac.state = 0; - gd54xx->ramdac.ctrl = val; - svga_recalctimings(svga); - return; - } - gd54xx->ramdac.state = 0; - break; - case 0x3C9: - 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: - if (svga->seqregs[0x12] & 2) { - gd54xx->extpal[svga->dac_write].r = svga->dac_r; - gd54xx->extpal[svga->dac_write].g = svga->dac_g; - gd54xx->extpal[svga->dac_write].b = val; - gd54xx->extpallook[svga->dac_write & 15] = makecol32(video_6to8[gd54xx->extpal[svga->dac_write].r & 0x3f], video_6to8[gd54xx->extpal[svga->dac_write].g & 0x3f], video_6to8[gd54xx->extpal[svga->dac_write].b & 0x3f]); - if ((svga->seqregs[0x12] & 0x80) && ((svga->dac_write & 15) == 2)) { - o32 = svga->overscan_color; - svga->overscan_color = gd54xx->extpallook[2]; - if (o32 != svga->overscan_color) - svga_recalctimings(svga); - } - svga->dac_write = (svga->dac_write + 1) & 15; - } else { - svga->vgapal[svga->dac_write].r = svga->dac_r; - svga->vgapal[svga->dac_write].g = svga->dac_g; - svga->vgapal[svga->dac_write].b = val; - svga->pallook[svga->dac_write] = makecol32(video_6to8[svga->vgapal[svga->dac_write].r & 0x3f], video_6to8[svga->vgapal[svga->dac_write].g & 0x3f], video_6to8[svga->vgapal[svga->dac_write].b & 0x3f]); - svga->dac_write = (svga->dac_write + 1) & 255; - } - svga->dac_pos = 0; - break; - } - return; - case 0x3cf: - if (svga->gdcaddr == 0) - gd543x_mmio_write(0xb8000, val, gd54xx); - if (svga->gdcaddr == 1) - gd543x_mmio_write(0xb8004, val, gd54xx); - - if (svga->gdcaddr == 5) { - svga->gdcreg[5] = val; - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = svga->gdcreg[5] & 7; - else - svga->writemode = svga->gdcreg[5] & 3; - svga->readmode = val & 8; - svga->chain2_read = val & 0x10; - return; - } - - if (svga->gdcaddr == 6) { - if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { - svga->gdcreg[6] = val; - gd543x_recalc_mapping(gd54xx); - } - svga->gdcreg[6] = val; - return; - } - - if (svga->gdcaddr > 8) { - svga->gdcreg[svga->gdcaddr & 0x3f] = val; - switch (svga->gdcaddr) { - case 0x09: case 0x0a: case 0x0b: - gd54xx_recalc_banking(gd54xx); - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = svga->gdcreg[5] & 7; - else - svga->writemode = svga->gdcreg[5] & 3; - break; - - case 0x10: - gd543x_mmio_write(0xb8001, val, gd54xx); - break; - case 0x11: - gd543x_mmio_write(0xb8005, val, gd54xx); - break; - case 0x12: - gd543x_mmio_write(0xb8002, val, gd54xx); - break; - case 0x13: - gd543x_mmio_write(0xb8006, val, gd54xx); - break; - case 0x14: - gd543x_mmio_write(0xb8003, val, gd54xx); - break; - case 0x15: - gd543x_mmio_write(0xb8007, val, gd54xx); - break; - - case 0x20: - gd543x_mmio_write(0xb8008, val, gd54xx); - break; - case 0x21: - gd543x_mmio_write(0xb8009, val, gd54xx); - break; - case 0x22: - gd543x_mmio_write(0xb800a, val, gd54xx); - break; - case 0x23: - gd543x_mmio_write(0xb800b, val, gd54xx); - break; - case 0x24: - gd543x_mmio_write(0xb800c, val, gd54xx); - break; - case 0x25: - gd543x_mmio_write(0xb800d, val, gd54xx); - break; - case 0x26: - gd543x_mmio_write(0xb800e, val, gd54xx); - break; - case 0x27: - gd543x_mmio_write(0xb800f, val, gd54xx); - break; - - case 0x28: - gd543x_mmio_write(0xb8010, val, gd54xx); - break; - case 0x29: - gd543x_mmio_write(0xb8011, val, gd54xx); - break; - case 0x2a: - gd543x_mmio_write(0xb8012, val, gd54xx); - break; - - case 0x2c: - gd543x_mmio_write(0xb8014, val, gd54xx); - break; - case 0x2d: - gd543x_mmio_write(0xb8015, val, gd54xx); - break; - case 0x2e: - gd543x_mmio_write(0xb8016, val, gd54xx); - break; - - case 0x2f: - gd543x_mmio_write(0xb8017, val, gd54xx); - break; - case 0x30: - gd543x_mmio_write(0xb8018, val, gd54xx); - break; - - case 0x32: - gd543x_mmio_write(0xb801a, val, gd54xx); - break; - - case 0x33: - gd543x_mmio_write(0xb801b, val, gd54xx); - break; - - case 0x31: - gd543x_mmio_write(0xb8040, val, gd54xx); - break; - - case 0x34: - gd543x_mmio_write(0xb801c, val, gd54xx); - break; - - case 0x35: - gd543x_mmio_write(0xb801d, val, gd54xx); - break; - - case 0x38: - gd543x_mmio_write(0xb8020, val, gd54xx); - break; - - case 0x39: - gd543x_mmio_write(0xb8021, val, gd54xx); - break; - - } - return; - } - break; - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); -} - - -static uint8_t -gd54xx_in(uint16_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - uint8_t temp; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3d0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) { - case 0x3c4: - if ((svga->seqregs[6] & 0x17) == 0x12) - { - temp = svga->seqaddr; - if ((temp & 0x1e) == 0x10) - { - if (temp & 1) - temp = ((svga->hwcursor.y & 7) << 5) | 0x11; - else - temp = ((svga->hwcursor.x & 7) << 5) | 0x10; - } - return temp; - } - return svga->seqaddr; - - case 0x3c5: - if (svga->seqaddr > 5) { - switch (svga->seqaddr) { - case 6: - return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; - case 0x0b: case 0x0c: case 0x0d: case 0x0e: - return gd54xx->vclk_n[svga->seqaddr-0x0b]; - case 0x17: - temp = svga->gdcreg[0x17] & ~(7 << 3); - if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) { - if (gd54xx->vlb) - temp |= (CL_GD5429_SYSTEM_BUS_VESA << 3); - else - temp |= (CL_GD5429_SYSTEM_BUS_ISA << 3); - } else { - if (gd54xx->pci) - temp |= (CL_GD543X_SYSTEM_BUS_PCI << 3); - else if (gd54xx->vlb) - temp |= (CL_GD543X_SYSTEM_BUS_VESA << 3); - else - temp |= (CL_GD543X_SYSTEM_BUS_ISA << 3); - } - return temp; - case 0x1b: case 0x1c: case 0x1d: case 0x1e: - return gd54xx->vclk_d[svga->seqaddr-0x1b]; - } - return svga->seqregs[svga->seqaddr & 0x3f]; - } - break; - case 0x3c9: - svga->dac_status = 3; - switch (svga->dac_pos) { - case 0: - svga->dac_pos++; - if (svga->seqregs[0x12] & 2) - return gd54xx->extpal[svga->dac_read].r & 0x3f; - else - return svga->vgapal[svga->dac_read].r & 0x3f; - case 1: - svga->dac_pos++; - if (svga->seqregs[0x12] & 2) - return gd54xx->extpal[svga->dac_read].g & 0x3f; - else - return svga->vgapal[svga->dac_read].g & 0x3f; - case 2: - svga->dac_pos=0; - if (svga->seqregs[0x12] & 2) { - svga->dac_read = (svga->dac_read + 1) & 15; - return gd54xx->extpal[(svga->dac_read - 1) & 15].b & 0x3f; - } else { - svga->dac_read = (svga->dac_read + 1) & 255; - return svga->vgapal[(svga->dac_read - 1) & 255].b & 0x3f; - } - } - return 0xFF; - case 0x3C6: - if (gd54xx->ramdac.state == 4) { - gd54xx->ramdac.state = 0; - return gd54xx->ramdac.ctrl; - } - gd54xx->ramdac.state++; - break; - case 0x3cf: - if (svga->gdcaddr > 8) { - return svga->gdcreg[svga->gdcaddr & 0x3f]; - } - break; - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - switch (svga->crtcreg) { - case 0x24: /*Attribute controller toggle readback (R)*/ - return svga->attrff << 7; - case 0x26: /*Attribute controller index readback (R)*/ - return svga->attraddr & 0x3f; - case 0x27: /*ID*/ - return svga->crtc[0x27]; /*GD542x/GD543x*/ - case 0x28: /*Class ID*/ - if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5430) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5440)) - return 0xff; /*Standard CL-GD5430/40*/ - break; - } - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); -} - - -static void -gd54xx_recalc_banking(gd54xx_t *gd54xx) -{ - svga_t *svga = &gd54xx->svga; - - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) - gd54xx->bank[0] = svga->gdcreg[0x09] << 14; - else - gd54xx->bank[0] = svga->gdcreg[0x09] << 12; - - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) { - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) - gd54xx->bank[1] = svga->gdcreg[0x0a] << 14; - else - gd54xx->bank[1] = svga->gdcreg[0x0a] << 12; - } else - gd54xx->bank[1] = gd54xx->bank[0] + 0x8000; -} - - -static void -gd543x_recalc_mapping(gd54xx_t *gd54xx) -{ - svga_t *svga = &gd54xx->svga; - - if (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&gd54xx->linear_mapping); - mem_mapping_disable(&gd54xx->mmio_mapping); - return; - } - - gd54xx->mmio_vram_overlap = 0; - - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_disable(&gd54xx->linear_mapping); - switch (svga->gdcreg[6] & 0x0c) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - gd54xx->mmio_vram_overlap = 1; - break; - } - if (svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) - mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x00100); - else - mem_mapping_disable(&gd54xx->mmio_mapping); - } else { - uint32_t base, size; - - if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429 || (!gd54xx->pci && !gd54xx->vlb)) { - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) { - base = (svga->seqregs[7] & 0xf0) << 16; - size = 1 * 1024 * 1024; - } else { - base = (svga->seqregs[7] & 0xe0) << 16; - size = 2 * 1024 * 1024; - } - } else if (gd54xx->pci) { - base = gd54xx->lfb_base; - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - size = 16 * 1024 * 1024; - else - size = 4 * 1024 * 1024; - } else { /*VLB*/ - base = 128*1024*1024; - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - size = 16 * 1024 * 1024; - else - size = 4 * 1024 * 1024; - } - - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&gd54xx->linear_mapping, base, size); - if (svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) { - if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) { - if (size >= (4 * 1024 * 1024)) - mem_mapping_disable(&gd54xx->mmio_mapping); /* MMIO is handled in the linear read/write functions */ - else { - mem_mapping_set_addr(&gd54xx->linear_mapping, base, size - 256); - mem_mapping_set_addr(&gd54xx->mmio_mapping, base + size - 256, 0x00100); - } - } else - mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x00100); - } else - mem_mapping_disable(&gd54xx->mmio_mapping); - } -} - - -static void -gd54xx_recalctimings(svga_t *svga) -{ - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - uint8_t clocksel; - - svga->rowoffset = (svga->crtc[0x13]) | ((svga->crtc[0x1b] & 0x10) << 4); - - svga->interlace = (svga->crtc[0x1a] & 0x01); - - if (svga->seqregs[7] & CIRRUS_SR7_BPP_SVGA) - svga->render = svga_render_8bpp_highres; - else if (svga->gdcreg[5] & 0x40) - svga->render = svga_render_8bpp_lowres; - - svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); - - svga->bpp = 8; - - if (gd54xx->ramdac.ctrl & 0x80) { - if (gd54xx->ramdac.ctrl & 0x40) { - switch (gd54xx->ramdac.ctrl & 0xf) { - case 0: - svga->bpp = 15; - svga->render = svga_render_15bpp_highres; - break; - - case 1: - svga->bpp = 16; - svga->render = svga_render_16bpp_highres; - break; - - case 5: - if (gd54xx_is_5434(svga) && (svga->seqregs[7] & CIRRUS_SR7_BPP_32)) { - svga->bpp = 32; - svga->render = svga_render_32bpp_highres; - if (svga->crtc[0x27] < CIRRUS_ID_CLGD5436) - svga->rowoffset *= 2; - } else { - svga->bpp = 24; - svga->render = svga_render_24bpp_highres; - } - break; - - case 0xf: - switch (svga->seqregs[7] & CIRRUS_SR7_BPP_MASK) { - case CIRRUS_SR7_BPP_32: - svga->bpp = 32; - svga->render = svga_render_32bpp_highres; - svga->rowoffset *= 2; - break; - - case CIRRUS_SR7_BPP_24: - svga->bpp = 24; - svga->render = svga_render_24bpp_highres; - break; - - case CIRRUS_SR7_BPP_16: - case CIRRUS_SR7_BPP_16_DOUBLEVCLK: - svga->bpp = 16; - svga->render = svga_render_16bpp_highres; - break; - - case CIRRUS_SR7_BPP_8: - svga->bpp = 8; - svga->render = svga_render_8bpp_highres; - break; - } - break; - } - } else { - svga->bpp = 15; - svga->render = svga_render_15bpp_highres; - } - } - - clocksel = (svga->miscout >> 2) & 3; - - if (!gd54xx->vclk_n[clocksel] || !gd54xx->vclk_d[clocksel]) - svga->clock = cpuclock / ((svga->miscout & 0xc) ? 28322000.0 : 25175000.0); - else { - int n = gd54xx->vclk_n[clocksel] & 0x7f; - int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; - int m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; - float freq = (14318184.0 * ((float)n / ((float)d * m))); - switch (svga->seqregs[7] & (gd54xx_is_5434(svga) ? 0xe : 6)) { - case 2: - freq /= 2.0; - break; - case 4: - if (!gd54xx_is_5434(svga)) - freq /= 3.0; - break; - } - svga->clock = cpuclock / freq; - } - - svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff; -} - -static -void gd54xx_hwcursor_draw(svga_t *svga, int displine) -{ - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - int x, xx, comb, b0, b1; - uint8_t dat[2]; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - int pitch = (svga->hwcursor.xsize == 64) ? 16 : 4; - uint32_t bgcol = gd54xx->extpallook[0x00]; - uint32_t fgcol = gd54xx->extpallook[0x0f]; - - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; - - for (x = 0; x < svga->hwcursor.xsize; x += 8) { - dat[0] = svga->vram[svga->hwcursor_latch.addr]; - if (svga->hwcursor.xsize == 64) - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x08]; - else - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; - for (xx = 0; xx < 8; xx++) { - b0 = (dat[0] >> (7 - xx)) & 1; - b1 = (dat[1] >> (7 - xx)) & 1; - comb = (b1 | (b0 << 1)); - if (offset >= svga->hwcursor_latch.x) { - switch(comb) { - case 0: - /* The original screen pixel is shown (invisible cursor) */ - break; - case 1: - /* The pixel is shown in the cursor background color */ - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = bgcol; - break; - case 2: - /* The pixel is shown as the inverse of the original screen pixel - (XOR cursor) */ - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; - break; - case 3: - /* The pixel is shown in the cursor foreground color */ - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = fgcol; - break; - } - } - - offset++; - } - svga->hwcursor_latch.addr++; - } - - if (svga->hwcursor.xsize == 64) - svga->hwcursor_latch.addr += 8; - - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; -} - -static void -gd54xx_memsrc_rop(gd54xx_t *gd54xx, svga_t *svga, uint8_t src, uint8_t dst) -{ - uint8_t res = src; - svga->changedvram[(gd54xx->blt.dst_addr_backup & svga->vram_mask) >> 12] = changeframecount; - - switch (gd54xx->blt.rop) { - case 0x00: res = 0; break; - case 0x05: res = src & dst; break; - case 0x06: res = dst; break; - case 0x09: res = src & ~dst; break; - case 0x0b: res = ~ dst; break; - case 0x0d: res = src; break; - case 0x0e: res = 0xff; break; - case 0x50: res = ~ src & dst; break; - case 0x59: res = src ^ dst; break; - case 0x6d: res = src | dst; break; - case 0x90: res = ~(src | dst); break; - case 0x95: res = ~(src ^ dst); break; - case 0xad: res = src | ~dst; break; - case 0xd0: res = ~src; break; - case 0xd6: res = ~src | dst; break; - case 0xda: res = ~(src & dst); break; - } - - /* handle transparency compare */ - if(gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { /* TODO: 16-bit compare */ - /* if ROP result matches the transparency colour, don't change the pixel */ - if((res & (~gd54xx->blt.trans_mask & 0xff)) == ((gd54xx->blt.trans_col & 0xff) & (~gd54xx->blt.trans_mask & 0xff))) - return; - } - - svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask] = res; -} - - -/* non colour-expanded BitBLTs from system memory must be doubleword sized, extra bytes are ignored */ -static void -gd54xx_blit_dword(gd54xx_t *gd54xx, svga_t *svga) -{ - /* TODO: add support for reverse direction */ - uint8_t x, pixel; - - for (x=0;x<32;x+=8) { - pixel = ((gd54xx->blt.sys_buf & (0xff << x)) >> x); - if(gd54xx->blt.pixel_cnt <= gd54xx->blt.width) - gd54xx_memsrc_rop(gd54xx, svga, pixel, svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask]); - gd54xx->blt.dst_addr_backup++; - gd54xx->blt.pixel_cnt++; - } - if (gd54xx->blt.pixel_cnt > gd54xx->blt.width) { - gd54xx->blt.pixel_cnt = 0; - gd54xx->blt.scan_cnt++; - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr + (gd54xx->blt.dst_pitch*gd54xx->blt.scan_cnt); - } - if (gd54xx->blt.scan_cnt > gd54xx->blt.height) { - gd54xx->blt.sys_tx = 0; /* BitBLT complete */ - gd543x_recalc_mapping(gd54xx); - } -} - - -static void -gd54xx_blt_write_w(uint32_t addr, uint16_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - gd54xx_start_blit(val, 16, gd54xx, &gd54xx->svga); -} - - -static void -gd54xx_blt_write_l(uint32_t addr, uint32_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) == (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) { - gd54xx_start_blit(val & 0xff, 8, gd54xx, &gd54xx->svga); - gd54xx_start_blit((val>>8) & 0xff, 8, gd54xx, &gd54xx->svga); - gd54xx_start_blit((val>>16) & 0xff, 8, gd54xx, &gd54xx->svga); - gd54xx_start_blit((val>>24) & 0xff, 8, gd54xx, &gd54xx->svga); - } else - gd54xx_start_blit(val, 32, gd54xx, &gd54xx->svga); -} - - -static void -gd54xx_write(uint32_t addr, uint8_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd54xx->blt.sys_tx) { - if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { - gd54xx->blt.sys_buf &= ~(0xff << (gd54xx->blt.sys_cnt * 8)); - gd54xx->blt.sys_buf |= (val << (gd54xx->blt.sys_cnt * 8)); - gd54xx->blt.sys_cnt++; - if(gd54xx->blt.sys_cnt >= 4) { - gd54xx_blit_dword(gd54xx, svga); - gd54xx->blt.sys_cnt = 0; - } - } - return; - } - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - - svga_write_linear(addr, val, svga); -} - - -static void -gd54xx_writew(uint32_t addr, uint16_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd54xx->blt.sys_tx) - { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - return; - } - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - - if (svga->writemode < 4) - svga_writew_linear(addr, val, svga); - else { - svga_write_linear(addr, val, svga); - svga_write_linear(addr + 1, val >> 8, svga); - } -} - - -static void -gd54xx_writel(uint32_t addr, uint32_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd54xx->blt.sys_tx) - { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - gd54xx_write(addr+2, val >> 16, gd54xx); - gd54xx_write(addr+3, val >> 24, gd54xx); - return; - } - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - - if (svga->writemode < 4) - svga_writel_linear(addr, val, svga); - else { - svga_write_linear(addr, val, svga); - svga_write_linear(addr+1, val >> 8, svga); - svga_write_linear(addr+2, val >> 16, svga); - svga_write_linear(addr+3, val >> 24, svga); - } -} - - -/* This adds write modes 4 and 5 to SVGA. */ -static void -gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr) -{ - uint32_t i, j; - - switch (svga->writemode) { - case 4: - if (svga->gdcreg[0xb] & 0x10) { - addr <<= 2; - - for (i = 0; i < 8; i++) { - if (val & svga->seqregs[2] & (0x80 >> i)) { - svga->vram[addr + (i << 1)] = svga->gdcreg[1]; - svga->vram[addr + (i << 1) + 1] = svga->gdcreg[0x11]; - } - } - } else { - addr <<= 1; - - for (i = 0; i < 8; i++) { - if (val & svga->seqregs[2] & (0x80 >> i)) - svga->vram[addr + i] = svga->gdcreg[1]; - } - } - break; - - case 5: - if (svga->gdcreg[0xb] & 0x10) { - addr <<= 2; - - for (i = 0; i < 8; i++) { - j = (0x80 >> i); - if (svga->seqregs[2] & j) { - svga->vram[addr + (i << 1)] = (val & j) ? - svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + (i << 1) + 1] = (val & j) ? - svga->gdcreg[0x11] : svga->gdcreg[0x10]; - } - } - } else { - addr <<= 1; - - for (i = 0; i < 8; i++) { - j = (0x80 >> i); - if (svga->seqregs[2] & j) - svga->vram[addr + i] = (val & j) ? svga->gdcreg[1] : svga->gdcreg[0]; - } - } - break; - } - - svga->changedvram[addr >> 12] = changeframecount; -} - - -static uint8_t -gd54xx_get_aperture(uint32_t addr) -{ - uint32_t ap = addr >> 22; - return (uint8_t) (ap & 0x03); -} - - -static uint8_t -gd54xx_readb_linear(uint32_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - addr &= 0x003fffff; /* 4 MB mask */ - - switch (ap) { - case 0: - default: - break; - case 1: - /* 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2 */ - addr ^= 0x00000001; - break; - case 2: - /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ - addr ^= 0x00000003; - break; - case 3: - return 0xff; - } - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) - return gd543x_mmio_read(addr & 0x000000ff, gd54xx); - } - - return svga_read_linear(addr, p); -} - - -static uint16_t -gd54xx_readw_linear(uint32_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - uint16_t temp, temp2; - - addr &= 0x003fffff; /* 4 MB mask */ - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - if (ap == 2) - addr ^= 0x00000002; - - temp = gd543x_mmio_readw(addr & 0x000000ff, gd54xx); - - switch(ap) { - case 0: - default: - return temp; - case 1: - case 2: - temp2 = temp >> 8; - temp2 |= ((temp & 0xff) << 8); - return temp; - case 3: - return 0xffff; - } - } - } - - switch (ap) { - case 0: - default: - return svga_readw_linear(addr, p); - case 2: - /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ - addr ^= 0x00000002; - case 1: - temp = svga_readb_linear(addr + 1, p); - temp |= (svga_readb_linear(addr, p) << 8); - - if (svga->fast) - cycles -= video_timing_read_w; - - return temp; - case 3: - return 0xffff; - } -} - - -static uint32_t -gd54xx_readl_linear(uint32_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - uint32_t temp, temp2; - - addr &= 0x003fffff; /* 4 MB mask */ - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - temp = gd543x_mmio_readl(addr & 0x000000ff, gd54xx); - - switch(ap) { - case 0: - default: - return temp; - case 1: - temp2 = temp >> 24; - temp2 |= ((temp >> 16) & 0xff) << 8; - temp2 |= ((temp >> 8) & 0xff) << 16; - temp2 |= (temp & 0xff) << 24; - - return temp2; - case 2: - temp2 = (temp >> 8) & 0xff; - temp2 |= (temp & 0xff) << 8; - temp2 = ((temp >> 24) & 0xff) << 16; - temp2 = ((temp >> 16) & 0xff) << 24; - - return temp2; - case 3: - return 0xffffffff; - } - } - } - - switch (ap) { - case 0: - default: - return svga_readw_linear(addr, p); - case 1: - temp = svga_readb_linear(addr + 1, p); - temp |= (svga_readb_linear(addr, p) << 8); - temp |= (svga_readb_linear(addr + 3, p) << 16); - temp |= (svga_readb_linear(addr + 2, p) << 24); - - if (svga->fast) - cycles -= video_timing_read_l; - - return temp; - case 2: - temp = svga_readb_linear(addr + 3, p); - temp |= (svga_readb_linear(addr + 2, p) << 8); - temp |= (svga_readb_linear(addr + 1, p) << 16); - temp |= (svga_readb_linear(addr, p) << 24); - - if (svga->fast) - cycles -= video_timing_read_l; - - return temp; - case 3: - return 0xffffffff; - } -} - - -static void -gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - addr &= 0x003fffff; /* 4 MB mask */ - - switch (ap) { - case 0: - default: - break; - case 1: - /* 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2 */ - addr ^= 0x00000001; - break; - case 2: - /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ - addr ^= 0x00000003; - break; - case 3: - return; - } - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) - gd543x_mmio_write(addr & 0x000000ff, val, gd54xx); - } - - if (gd54xx->blt.sys_tx) { - if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { - gd54xx->blt.sys_buf &= ~(0xff << (gd54xx->blt.sys_cnt * 8)); - gd54xx->blt.sys_buf |= (val << (gd54xx->blt.sys_cnt * 8)); - gd54xx->blt.sys_cnt++; - if(gd54xx->blt.sys_cnt >= 4) { - gd54xx_blit_dword(gd54xx, svga); - gd54xx->blt.sys_cnt = 0; - } - } - return; - } - - svga_write_linear(addr, val, svga); -} - - -static void -gd54xx_writew_linear(uint32_t addr, uint16_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - uint16_t temp; - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - switch(ap) { - case 0: - default: - gd543x_mmio_writew(addr & 0x000000ff, val, gd54xx); - return; - case 2: - addr ^= 0x00000002; - case 1: - temp = (val >> 8); - temp |= ((val & 0xff) << 8); - gd543x_mmio_writew(addr & 0x000000ff, temp, gd54xx); - case 3: - return; - } - } - } - - if (gd54xx->blt.sys_tx) { - gd54xx_writeb_linear(addr, val, svga); - gd54xx_writeb_linear(addr+1, val >> 8, svga); - return; - } - - addr &= 0x003fffff; /* 4 MB mask */ - - if (svga->writemode < 4) { - switch(ap) { - case 0: - default: - svga_writew_linear(addr, val, svga); - return; - case 2: - addr ^= 0x00000002; - case 1: - svga_writeb_linear(addr + 1, val & 0xff, svga); - svga_writeb_linear(addr, val >> 8, svga); - - if (svga->fast) - cycles -= video_timing_write_w; - case 3: - return; - } - } else { - switch(ap) { - case 0: - default: - svga_write_linear(addr, val & 0xff, svga); - svga_write_linear(addr + 1, val >> 8, svga); - return; - case 2: - addr ^= 0x00000002; - case 1: - svga_write_linear(addr + 1, val & 0xff, svga); - svga_write_linear(addr, val >> 8, svga); - case 3: - return; - } - } -} - - -static void -gd54xx_writel_linear(uint32_t addr, uint32_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - uint32_t temp; - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - switch(ap) { - case 0: - default: - gd543x_mmio_writel(addr & 0x000000ff, val, gd54xx); - return; - case 2: - temp = (val >> 24); - temp |= ((val >> 16) & 0xff) << 8; - temp |= ((val >> 8) & 0xff) << 16; - temp |= (val & 0xff) << 24; - gd543x_mmio_writel(addr & 0x000000ff, temp, gd54xx); - return; - case 1: - temp = ((val >> 8) & 0xff); - temp |= (val & 0xff) << 8; - temp |= (val >> 24) << 16; - temp |= ((val >> 16) & 0xff) << 24; - gd543x_mmio_writel(addr & 0x000000ff, temp, gd54xx); - return; - case 3: - return; - } - } - } - - if (gd54xx->blt.sys_tx) { - gd54xx_writeb_linear(addr, val, svga); - gd54xx_writeb_linear(addr+1, val >> 8, svga); - gd54xx_writeb_linear(addr+2, val >> 16, svga); - gd54xx_writeb_linear(addr+3, val >> 24, svga); - return; - } - - addr &= 0x003fffff; /* 4 MB mask */ - - if (svga->writemode < 4) { - switch(ap) { - case 0: - default: - svga_writel_linear(addr, val, svga); - return; - case 1: - svga_writeb_linear(addr + 1, val & 0xff, svga); - svga_writeb_linear(addr, val >> 8, svga); - svga_writeb_linear(addr + 3, val >> 16, svga); - svga_writeb_linear(addr + 2, val >> 24, svga); - return; - case 2: - svga_writeb_linear(addr + 3, val & 0xff, svga); - svga_writeb_linear(addr + 2, val >> 8, svga); - svga_writeb_linear(addr + 1, val >> 16, svga); - svga_writeb_linear(addr, val >> 24, svga); - case 3: - return; - } - - if (svga->fast) - cycles -= video_timing_write_l; - } else { - switch(ap) { - case 0: - default: - svga_write_linear(addr, val & 0xff, svga); - svga_write_linear(addr+1, val >> 8, svga); - svga_write_linear(addr+2, val >> 16, svga); - svga_write_linear(addr+3, val >> 24, svga); - return; - case 1: - svga_write_linear(addr + 1, val & 0xff, svga); - svga_write_linear(addr, val >> 8, svga); - svga_write_linear(addr + 3, val >> 16, svga); - svga_write_linear(addr + 2, val >> 24, svga); - return; - case 2: - svga_write_linear(addr + 3, val & 0xff, svga); - svga_write_linear(addr + 2, val >> 8, svga); - svga_write_linear(addr + 1, val >> 16, svga); - svga_write_linear(addr, val >> 24, svga); - case 3: - return; - } - } -} - - -static uint8_t -gd54xx_read(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - return svga_read_linear(addr, svga); -} - - -static uint16_t -gd54xx_readw(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - return svga_readw_linear(addr, svga); -} - - -static uint32_t -gd54xx_readl(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - return svga_readl_linear(addr, svga); -} - - -static int -gd543x_do_mmio(svga_t *svga, uint32_t addr) -{ - if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) - return 1; - else - return ((addr & ~0xff) == 0xb8000); -} - - -static void -gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) { - switch (addr & 0xff) { - case 0x00: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xffffff00) | val; - else - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00) | val; - break; - case 0x01: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xffff00ff) | (val << 8); - else - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ff) | (val << 8); - break; - case 0x02: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00ffff) | (val << 16); - break; - case 0x03: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ffffff) | (val << 24); - break; - - case 0x04: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xffffff00) | val; - else - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00) | val; - break; - case 0x05: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xffff00ff) | (val << 8); - else - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ff) | (val << 8); - break; - case 0x06: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00ffff) | (val << 16); - break; - case 0x07: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ffffff) | (val << 24); - break; - - case 0x08: - gd54xx->blt.width = (gd54xx->blt.width & 0xff00) | val; - break; - case 0x09: - gd54xx->blt.width = (gd54xx->blt.width & 0x00ff) | (val << 8); - if (gd54xx_is_5434(svga)) - gd54xx->blt.width &= 0x1fff; - else - gd54xx->blt.width &= 0x07ff; - break; - case 0x0a: - gd54xx->blt.height = (gd54xx->blt.height & 0xff00) | val; - break; - case 0x0b: - gd54xx->blt.height = (gd54xx->blt.height & 0x00ff) | (val << 8); - gd54xx->blt.height &= 0x03ff; - break; - case 0x0c: - gd54xx->blt.dst_pitch = (gd54xx->blt.dst_pitch & 0xff00) | val; - break; - case 0x0d: - gd54xx->blt.dst_pitch = (gd54xx->blt.dst_pitch & 0x00ff) | (val << 8); - break; - case 0x0e: - gd54xx->blt.src_pitch = (gd54xx->blt.src_pitch & 0xff00) | val; - break; - case 0x0f: - gd54xx->blt.src_pitch = (gd54xx->blt.src_pitch & 0x00ff) | (val << 8); - break; - - case 0x10: - gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0xffff00) | val; - break; - case 0x11: - gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0xff00ff) | (val << 8); - break; - case 0x12: - gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0x00ffff) | (val << 16); - if (gd54xx_is_5434(svga)) - gd54xx->blt.dst_addr &= 0x3fffff; - else - gd54xx->blt.dst_addr &= 0x1fffff; - - if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) && (gd54xx->blt.status & CIRRUS_BLT_AUTOSTART)) { - if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { - gd54xx->blt.sys_tx = 1; - gd54xx->blt.sys_cnt = 0; - gd54xx->blt.sys_buf = 0; - gd54xx->blt.pixel_cnt = gd54xx->blt.scan_cnt = 0; - gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; - } else - gd54xx_start_blit(0, -1, gd54xx, svga); - } - break; - - case 0x14: - gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0xffff00) | val; - break; - case 0x15: - gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0xff00ff) | (val << 8); - break; - case 0x16: - gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0x00ffff) | (val << 16); - if (gd54xx_is_5434(svga)) - gd54xx->blt.src_addr &= 0x3fffff; - else - gd54xx->blt.src_addr &= 0x1fffff; - break; - - case 0x17: - gd54xx->blt.mask = val; - break; - case 0x18: - gd54xx->blt.mode = val; - break; - - case 0x1a: - gd54xx->blt.rop = val; - break; - - case 0x1b: - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - gd54xx->blt.modeext = val; - break; - - case 0x1c: - gd54xx->blt.trans_col = (gd54xx->blt.trans_col & 0xff00) | val; - break; - - case 0x1d: - gd54xx->blt.trans_col = (gd54xx->blt.trans_col & 0x00ff) | (val << 8); - break; - - case 0x20: - gd54xx->blt.trans_mask = (gd54xx->blt.trans_mask & 0xff00) | val; - break; - - case 0x21: - gd54xx->blt.trans_mask = (gd54xx->blt.trans_mask & 0x00ff) | (val << 8); - break; - - case 0x40: - gd54xx->blt.status = val; - if (gd54xx->blt.status & CIRRUS_BLT_START) { - if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { - gd54xx->blt.sys_tx = 1; - gd54xx->blt.sys_cnt = 0; - gd54xx->blt.sys_buf = 0; - gd54xx->blt.pixel_cnt = gd54xx->blt.scan_cnt = 0; - gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; - } else - gd54xx_start_blit(0, -1, gd54xx, svga); - } - break; - } - } else if (gd54xx->mmio_vram_overlap) - gd54xx_write(addr, val, gd54xx); -} - - -static void -gd543x_mmio_writew(uint32_t addr, uint16_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) { - gd543x_mmio_write(addr, val & 0xff, gd54xx); - gd543x_mmio_write(addr+1, val >> 8, gd54xx); - } else if (gd54xx->mmio_vram_overlap) { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - } -} - - -static void -gd543x_mmio_writel(uint32_t addr, uint32_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) { - gd543x_mmio_write(addr, val & 0xff, gd54xx); - gd543x_mmio_write(addr+1, val >> 8, gd54xx); - gd543x_mmio_write(addr+2, val >> 16, gd54xx); - gd543x_mmio_write(addr+3, val >> 24, gd54xx); - } else if (gd54xx->mmio_vram_overlap) { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - gd54xx_write(addr+2, val >> 16, gd54xx); - gd54xx_write(addr+3, val >> 24, gd54xx); - } -} - - -static uint8_t -gd543x_mmio_read(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) { - switch (addr & 0xff) { - case 0x40: /*BLT status*/ - return 0; - } - return 0xff; /*All other registers read-only*/ - } - else if (gd54xx->mmio_vram_overlap) - return gd54xx_read(addr, gd54xx); - return 0xff; -} - - -static uint16_t -gd543x_mmio_readw(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) - return gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr+1, gd54xx) << 8); - else if (gd54xx->mmio_vram_overlap) - return gd54xx_read(addr, gd54xx) | (gd54xx_read(addr+1, gd54xx) << 8); - return 0xffff; -} - - -static uint32_t -gd543x_mmio_readl(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) - return gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr+1, gd54xx) << 8) | (gd543x_mmio_read(addr+2, gd54xx) << 16) | (gd543x_mmio_read(addr+3, gd54xx) << 24); - else if (gd54xx->mmio_vram_overlap) - return gd54xx_read(addr, gd54xx) | (gd54xx_read(addr+1, gd54xx) << 8) | (gd54xx_read(addr+2, gd54xx) << 16) | (gd54xx_read(addr+3, gd54xx) << 24); - return 0xffffffff; -} - - -static void -gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) -{ - int blt_mask = 0; - int x_max = 0; - - int shift = 0, last_x = 0; - - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - blt_mask = gd54xx->blt.mask & 7; - x_max = 8; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - blt_mask = gd54xx->blt.mask & 7; - x_max = 16; - blt_mask *= 2; - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - blt_mask = (gd54xx->blt.mask & 0x1f); - x_max = 24; - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - blt_mask = gd54xx->blt.mask & 7; - x_max = 32; - blt_mask *= 4; - break; - } - - last_x = (x_max >> 3) - 1; - - if (count == -1) { - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; - gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; - gd54xx->blt.width_backup = gd54xx->blt.width; - gd54xx->blt.height_internal = gd54xx->blt.height; - gd54xx->blt.x_count = 0; - if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) == (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) - gd54xx->blt.y_count = gd54xx->blt.src_addr & 7; - else - gd54xx->blt.y_count = 0; - - if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) { - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_set_handler(&svga->mapping, NULL, NULL, NULL, NULL, gd54xx_blt_write_w, gd54xx_blt_write_l); - mem_mapping_set_p(&svga->mapping, gd54xx); - } else { - mem_mapping_set_handler(&gd54xx->linear_mapping, NULL, NULL, NULL, NULL, gd54xx_blt_write_w, gd54xx_blt_write_l); - mem_mapping_set_p(&gd54xx->linear_mapping, gd54xx); - } - gd543x_recalc_mapping(gd54xx); - return; - } else { - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); - mem_mapping_set_p(&gd54xx->svga.mapping, gd54xx); - } else { - mem_mapping_set_handler(&gd54xx->linear_mapping, svga_readb_linear, svga_readw_linear, svga_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear); - mem_mapping_set_p(&gd54xx->linear_mapping, svga); - } - gd543x_recalc_mapping(gd54xx); - } - } else if (gd54xx->blt.height_internal == 0xffff) - return; - - while (count) { - uint8_t src = 0, dst; - int mask = 0; - - if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) { - if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY) - mask = (cpu_dat >> 31); - else - mask = cpu_dat & 0x80; - - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; - shift = 0; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - shift = (gd54xx->blt.x_count & 1); - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - shift = (gd54xx->blt.x_count % 3); - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - shift = (gd54xx->blt.x_count & 3); - break; - } - - src = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); - - if (shift == last_x) { - cpu_dat <<= 1; - count--; - } - } else { - /*This must stay for general purpose Cirrus drivers to render fine in WinNT 3.5x*/ - src = cpu_dat & 0xff; - cpu_dat >>= 8; - count -= 8; - mask = 1; - } - } else { - switch (gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) { - case 0x00: - src = svga->vram[gd54xx->blt.src_addr & svga->vram_mask]; - gd54xx->blt.src_addr += ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -1 : 1); - mask = 1; - break; - case CIRRUS_BLTMODE_PATTERNCOPY: - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~7)) + (gd54xx->blt.y_count << 3) + (gd54xx->blt.x_count & 7)]; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~15)) + (gd54xx->blt.y_count << 4) + (gd54xx->blt.x_count & 15)]; - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~31)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count % 24)]; - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~31)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count & 31)]; - break; - } - mask = 1; - break; - case CIRRUS_BLTMODE_COLOREXPAND: - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> gd54xx->blt.x_count); - shift = 0; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count >> 1)); - shift = (gd54xx->blt.dst_addr & 1); - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count / 3)); - shift = (gd54xx->blt.dst_addr % 3); - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count >> 2)); - shift = (gd54xx->blt.dst_addr & 3); - break; - } - src = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); - break; - case CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND: - if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) { - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - shift = 0; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - shift = (gd54xx->blt.dst_addr & 1); - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - shift = (gd54xx->blt.dst_addr % 3); - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - shift = (gd54xx->blt.dst_addr & 3); - break; - } - src = (gd54xx->blt.fg_col >> (shift << 3)); - } else { - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> gd54xx->blt.x_count); - shift = 0; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count >> 1)); - shift = (gd54xx->blt.dst_addr & 1); - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count / 3)); - shift = (gd54xx->blt.dst_addr % 3); - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count >> 2)); - shift = (gd54xx->blt.dst_addr & 3); - break; - } - - src = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); - } - break; - } - count--; - } - dst = svga->vram[gd54xx->blt.dst_addr & svga->vram_mask]; - svga->changedvram[(gd54xx->blt.dst_addr & svga->vram_mask) >> 12] = changeframecount; - - switch (gd54xx->blt.rop) { - case 0x00: dst = 0; break; - case 0x05: dst = src & dst; break; - case 0x06: dst = dst; break; - case 0x09: dst = src & ~dst; break; - case 0x0b: dst = ~ dst; break; - case 0x0d: dst = src; break; - case 0x0e: dst = 0xff; break; - case 0x50: dst = ~ src & dst; break; - case 0x59: dst = src ^ dst; break; - case 0x6d: dst = src | dst; break; - case 0x90: dst = ~(src | dst); break; - case 0x95: dst = ~(src ^ dst); break; - case 0xad: dst = src | ~dst; break; - case 0xd0: dst = ~src; break; - case 0xd6: dst = ~src | dst; break; - case 0xda: dst = ~(src & dst); break; - } - - if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { - if ((gd54xx->blt.width_backup - gd54xx->blt.width) >= blt_mask && - !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && mask)) - svga->vram[gd54xx->blt.dst_addr & svga->vram_mask] = dst; - } else { - if ((gd54xx->blt.width_backup - gd54xx->blt.width) >= blt_mask && - !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !mask)) - svga->vram[gd54xx->blt.dst_addr & svga->vram_mask] = dst; - } - - gd54xx->blt.dst_addr += ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -1 : 1); - - gd54xx->blt.x_count++; - - if (gd54xx->blt.x_count == x_max) { - gd54xx->blt.x_count = 0; - if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) == CIRRUS_BLTMODE_COLOREXPAND) - gd54xx->blt.src_addr++; - } - - gd54xx->blt.width--; - - if (gd54xx->blt.width == 0xffff) { - gd54xx->blt.width = gd54xx->blt.width_backup; - - gd54xx->blt.dst_addr = gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr_backup + ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -gd54xx->blt.dst_pitch : gd54xx->blt.dst_pitch); - - switch (gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) { - case 0x00: - gd54xx->blt.src_addr = gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr_backup + ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -gd54xx->blt.src_pitch : gd54xx->blt.src_pitch); - break; - case CIRRUS_BLTMODE_COLOREXPAND: - if (gd54xx->blt.x_count != 0) - gd54xx->blt.src_addr++; - break; - } - - gd54xx->blt.x_count = 0; - if (gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) - gd54xx->blt.y_count = (gd54xx->blt.y_count - 1) & 7; - else - gd54xx->blt.y_count = (gd54xx->blt.y_count + 1) & 7; - - gd54xx->blt.height_internal--; - if (gd54xx->blt.height_internal == 0xffff) { - if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) { - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); - mem_mapping_set_p(&svga->mapping, gd54xx); - } else { - mem_mapping_set_handler(&gd54xx->linear_mapping, svga_readb_linear, svga_readw_linear, svga_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear); - mem_mapping_set_p(&gd54xx->linear_mapping, svga); - } - gd543x_recalc_mapping(gd54xx); - } - return; - } - - if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) - return; - } - } -} - - -static uint8_t -cl_pci_read(int func, int addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) - return 0; - - switch (addr) { - case 0x00: return 0x13; /*Cirrus Logic*/ - case 0x01: return 0x10; - - case 0x02: - return svga->crtc[0x27]; - case 0x03: return 0x00; - - case PCI_REG_COMMAND: - return gd54xx->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - - // case 0x07: return 0 << 1; /*Fast DEVSEL timing*/ - case 0x07: return 0x02; /*Fast DEVSEL timing*/ - - case 0x08: return gd54xx->rev; /*Revision ID*/ - case 0x09: return 0x00; /*Programming interface*/ - - case 0x0a: return 0x00; /*Supports VGA interface*/ - case 0x0b: return 0x03; - - case 0x10: return 0x08; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: return 0x00; - case 0x13: return gd54xx->lfb_base >> 24; - - case 0x30: return (gd54xx->pci_regs[0x30] & 0x01); /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return gd54xx->pci_regs[0x32]; - case 0x33: return gd54xx->pci_regs[0x33]; - - case 0x3c: return gd54xx->int_line; - case 0x3d: return PCI_INTA; - } - return 0; -} - - -static void -cl_pci_write(int func, int addr, uint8_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) - return; - - switch (addr) { - case PCI_REG_COMMAND: - gd54xx->pci_regs[PCI_REG_COMMAND] = val & 0x23; - io_removehandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - if (val & PCI_COMMAND_IO) - io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - gd543x_recalc_mapping(gd54xx); - break; - - case 0x13: - gd54xx->lfb_base = val << 24; - gd543x_recalc_mapping(gd54xx); - break; - - case 0x30: case 0x32: case 0x33: - gd54xx->pci_regs[addr] = val; - if (gd54xx->pci_regs[0x30] & 0x01) { - uint32_t addr = (gd54xx->pci_regs[0x32] << 16) | (gd54xx->pci_regs[0x33] << 24); - mem_mapping_set_addr(&gd54xx->bios_rom.mapping, addr, 0x8000); - } else - mem_mapping_disable(&gd54xx->bios_rom.mapping); - return; - - case 0x3c: - gd54xx->int_line = val; - return; - } -} - - -static void -*gd54xx_init(const device_t *info) -{ - gd54xx_t *gd54xx = malloc(sizeof(gd54xx_t)); - svga_t *svga = &gd54xx->svga; - int id = info->local & 0xff; - wchar_t *romfn = NULL; - memset(gd54xx, 0, sizeof(gd54xx_t)); - - gd54xx->pci = !!(info->flags & DEVICE_PCI); - gd54xx->vlb = !!(info->flags & DEVICE_VLB); - - gd54xx->rev = 0; - gd54xx->has_bios = 1; - switch (id) { - case CIRRUS_ID_CLGD5426: - romfn = BIOS_GD5426_PATH; - break; - - case CIRRUS_ID_CLGD5428: - if (gd54xx->vlb) - romfn = BIOS_GD5428_PATH; - else - romfn = BIOS_GD5428_ISA_PATH; - break; - - case CIRRUS_ID_CLGD5429: - romfn = BIOS_GD5429_PATH; - break; - - case CIRRUS_ID_CLGD5434: - romfn = BIOS_GD5434_PATH; - break; - - case CIRRUS_ID_CLGD5436: - romfn = BIOS_GD5436_PATH; - break; - - case CIRRUS_ID_CLGD5430: - if (info->local & 0x400) { - /* CL-GD 5440 */ - gd54xx->rev = 0x47; - if (info->local & 0x200) { - romfn = NULL; - gd54xx->has_bios = 0; - } else - romfn = BIOS_GD5440_PATH; - } else { - /* CL-GD 5430 */ - if (gd54xx->pci) - romfn = BIOS_GD5430_PCI_PATH; - else - romfn = BIOS_GD5430_VLB_PATH; - } - break; - - case CIRRUS_ID_CLGD5446: - if (info->local & 0x100) - romfn = BIOS_GD5446_STB_PATH; - else - romfn = BIOS_GD5446_PATH; - break; - - case CIRRUS_ID_CLGD5480: - romfn = BIOS_GD5480_PATH; - break; - } - - gd54xx->vram_size = device_get_config_int("memory"); - gd54xx->vram_mask = (gd54xx->vram_size << 20) - 1; - - if (romfn) - rom_init(&gd54xx->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - svga_init(&gd54xx->svga, gd54xx, gd54xx->vram_size << 20, - gd54xx_recalctimings, gd54xx_in, gd54xx_out, - gd54xx_hwcursor_draw, NULL); - svga_set_ven_write(&gd54xx->svga, gd54xx_write_modes45); - - mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); - mem_mapping_set_p(&svga->mapping, gd54xx); - - mem_mapping_add(&gd54xx->mmio_mapping, 0, 0, gd543x_mmio_read, gd543x_mmio_readw, gd543x_mmio_readl, gd543x_mmio_write, gd543x_mmio_writew, gd543x_mmio_writel, NULL, 0, gd54xx); - mem_mapping_add(&gd54xx->linear_mapping, 0, 0, gd54xx_readb_linear, gd54xx_readw_linear, gd54xx_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear, NULL, 0, svga); - - io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - - svga->hwcursor.yoff = 32; - svga->hwcursor.xoff = 0; - - gd54xx->vclk_n[0] = 0x4a; - gd54xx->vclk_d[0] = 0x2b; - gd54xx->vclk_n[1] = 0x5b; - gd54xx->vclk_d[1] = 0x2f; - - gd54xx->bank[1] = 0x8000; - - if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430) - pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx); - - gd54xx->pci_regs[PCI_REG_COMMAND] = 7; - - gd54xx->pci_regs[0x30] = 0x00; - gd54xx->pci_regs[0x32] = 0x0c; - gd54xx->pci_regs[0x33] = 0x00; - - svga->crtc[0x27] = id; - - return gd54xx; -} - -static int -gd5426_available(void) -{ - return rom_present(BIOS_GD5426_PATH); -} - -static int -gd5428_available(void) -{ - return rom_present(BIOS_GD5428_PATH); -} - -static int -gd5428_isa_available(void) -{ - return rom_present(BIOS_GD5428_ISA_PATH); -} - -static int -gd5429_available(void) -{ - return rom_present(BIOS_GD5429_PATH); -} - -static int -gd5430_vlb_available(void) -{ - return rom_present(BIOS_GD5430_VLB_PATH); -} - -static int -gd5430_pci_available(void) -{ - return rom_present(BIOS_GD5430_PCI_PATH); -} - -static int -gd5434_available(void) -{ - return rom_present(BIOS_GD5434_PATH); -} - -static int -gd5436_available(void) -{ - return rom_present(BIOS_GD5436_PATH); -} - -static int -gd5440_available(void) -{ - return rom_present(BIOS_GD5440_PATH); -} - -static int -gd5446_available(void) -{ - return rom_present(BIOS_GD5446_PATH); -} - -static int -gd5446_stb_available(void) -{ - return rom_present(BIOS_GD5446_STB_PATH); -} - -static int -gd5480_available(void) -{ - return rom_present(BIOS_GD5480_PATH); -} - -void -gd54xx_close(void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - svga_close(&gd54xx->svga); - - free(gd54xx); -} - - -void -gd54xx_speed_changed(void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - svga_recalctimings(&gd54xx->svga); -} - - -void -gd54xx_force_redraw(void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - gd54xx->svga.fullchange = changeframecount; -} - - -static const device_config_t gd5428_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } -}; - -static const device_config_t gd5440_onboard_config[] = -{ - { - .name = "memory", - .description = "Video memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } -}; - -static const device_config_t gd5434_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } -}; - -const device_t gd5426_vlb_device = -{ - "Cirrus Logic CL-GD 5426 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5426, - gd54xx_init, - gd54xx_close, - NULL, - gd5426_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5428_isa_device = -{ - "Cirrus Logic CL-GD 5428 (ISA)", - DEVICE_AT | DEVICE_ISA, - CIRRUS_ID_CLGD5428, - gd54xx_init, - gd54xx_close, - NULL, - gd5428_isa_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5428_vlb_device = -{ - "Cirrus Logic CL-GD 5428 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5428, - gd54xx_init, - gd54xx_close, - NULL, - gd5428_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5429_isa_device = -{ - "Cirrus Logic CL-GD 5429 (ISA)", - DEVICE_AT | DEVICE_ISA, - CIRRUS_ID_CLGD5429, - gd54xx_init, - gd54xx_close, - NULL, - gd5429_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5429_vlb_device = -{ - "Cirrus Logic CL-GD 5429 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5429, - gd54xx_init, - gd54xx_close, - NULL, - gd5429_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5430_vlb_device = -{ - "Cirrus Logic CL-GD 5430 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5430, - gd54xx_init, - gd54xx_close, - NULL, - gd5430_vlb_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5430_pci_device = -{ - "Cirrus Logic CL-GD 5430 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5430, - gd54xx_init, - gd54xx_close, - NULL, - gd5430_pci_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5434_isa_device = -{ - "Cirrus Logic CL-GD 5434 (ISA)", - DEVICE_AT | DEVICE_ISA, - CIRRUS_ID_CLGD5434, - gd54xx_init, - gd54xx_close, - NULL, - gd5434_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5434_vlb_device = -{ - "Cirrus Logic CL-GD 5434 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5434, - gd54xx_init, - gd54xx_close, - NULL, - gd5434_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5434_pci_device = -{ - "Cirrus Logic CL-GD 5434 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5434, - gd54xx_init, - gd54xx_close, - NULL, - gd5434_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5436_pci_device = -{ - "Cirrus Logic CL-GD 5436 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5436, - gd54xx_init, - gd54xx_close, - NULL, - gd5436_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5440_onboard_pci_device = -{ - "Cirrus Logic CL-GD 5440 (On-Board PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5440 | 0x600, - gd54xx_init, - gd54xx_close, - NULL, - NULL, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5440_onboard_config -}; - -const device_t gd5440_pci_device = -{ - "Cirrus Logic CL-GD 5440 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5440 | 0x400, - gd54xx_init, - gd54xx_close, - NULL, - gd5440_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5446_pci_device = -{ - "Cirrus Logic CL-GD 5446 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5446, - gd54xx_init, - gd54xx_close, - NULL, - gd5446_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5446_stb_pci_device = -{ - "STB Nitro 64V (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5446 | 0x100, - gd54xx_init, - gd54xx_close, - NULL, - gd5446_stb_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5480_pci_device = -{ - "Cirrus Logic CL-GD 5480 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5480, - gd54xx_init, - gd54xx_close, - NULL, - gd5480_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; diff --git a/backup code/video - Cópia/vid_cl54xx.h b/backup code/video - Cópia/vid_cl54xx.h deleted file mode 100644 index 654a6326e..000000000 --- a/backup code/video - Cópia/vid_cl54xx.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t gd5426_vlb_device; -extern const device_t gd5428_isa_device; -extern const device_t gd5428_vlb_device; -extern const device_t gd5429_isa_device; -extern const device_t gd5429_vlb_device; -extern const device_t gd5430_vlb_device; -extern const device_t gd5430_pci_device; -extern const device_t gd5434_isa_device; -extern const device_t gd5434_vlb_device; -extern const device_t gd5434_pci_device; -extern const device_t gd5436_pci_device; -extern const device_t gd5440_onboard_pci_device; -extern const device_t gd5440_pci_device; -extern const device_t gd5446_pci_device; -extern const device_t gd5446_stb_pci_device; -extern const device_t gd5480_pci_device; \ No newline at end of file diff --git a/backup code/video - Cópia/vid_colorplus.c b/backup code/video - Cópia/vid_colorplus.c deleted file mode 100644 index 95d82c70f..000000000 --- a/backup code/video - Cópia/vid_colorplus.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * 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. - * - * Plantronics ColorPlus emulation. - * - * Version: @(#)vid_colorplus.c 1.0.9 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../lpt.h" -#include "../pit.h" -#include "../mem.h" -#include "../timer.h" -#include "../device.h" -#include "video.h" -#include "vid_cga.h" -#include "vid_colorplus.h" -#include "vid_cga_comp.h" - - -/* Bits in the colorplus control register: */ -#define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */ -#define COLORPLUS_640x200_MODE 0x20 /* 640x200x4 mode active */ -#define COLORPLUS_320x200_MODE 0x10 /* 320x200x16 mode active */ -#define COLORPLUS_EITHER_MODE 0x30 /* Either mode active */ - -/* Bits in the CGA graphics mode register */ -#define CGA_GRAPHICS_MODE 0x02 /* CGA graphics mode selected? */ - -#define CGA_RGB 0 -#define CGA_COMPOSITE 1 - -#define COMPOSITE_OLD 0 -#define COMPOSITE_NEW 1 - - -void cga_recalctimings(cga_t *cga); - -void colorplus_out(uint16_t addr, uint8_t val, void *p) -{ - colorplus_t *colorplus = (colorplus_t *)p; - - if (addr == 0x3DD) - { - colorplus->control = val & 0x70; - } - else - { - cga_out(addr, val, &colorplus->cga); - } -} - -uint8_t colorplus_in(uint16_t addr, void *p) -{ - colorplus_t *colorplus = (colorplus_t *)p; - - return cga_in(addr, &colorplus->cga); -} - -void colorplus_write(uint32_t addr, uint8_t val, void *p) -{ - colorplus_t *colorplus = (colorplus_t *)p; - - if ((colorplus->control & COLORPLUS_PLANE_SWAP) && - (colorplus->control & COLORPLUS_EITHER_MODE) && - (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) - { - addr ^= 0x4000; - } - else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) - { - addr &= 0x3FFF; - } - colorplus->cga.vram[addr & 0x7fff] = val; - if (colorplus->cga.snow_enabled) - { - colorplus->cga.charbuffer[ ((int)(((colorplus->cga.dispontime - colorplus->cga.vidtime) * 2) / CGACONST)) & 0xfc] = val; - colorplus->cga.charbuffer[(((int)(((colorplus->cga.dispontime - colorplus->cga.vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val; - } - egawrites++; - cycles -= 4; -} - -uint8_t colorplus_read(uint32_t addr, void *p) -{ - colorplus_t *colorplus = (colorplus_t *)p; - - if ((colorplus->control & COLORPLUS_PLANE_SWAP) && - (colorplus->control & COLORPLUS_EITHER_MODE) && - (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) - { - addr ^= 0x4000; - } - else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) - { - addr &= 0x3FFF; - } - cycles -= 4; - if (colorplus->cga.snow_enabled) - { - colorplus->cga.charbuffer[ ((int)(((colorplus->cga.dispontime - colorplus->cga.vidtime) * 2) / CGACONST)) & 0xfc] = colorplus->cga.vram[addr & 0x7fff]; - colorplus->cga.charbuffer[(((int)(((colorplus->cga.dispontime - colorplus->cga.vidtime) * 2) / CGACONST)) & 0xfc) | 1] = colorplus->cga.vram[addr & 0x7fff]; - } - egareads++; - return colorplus->cga.vram[addr & 0x7fff]; -} - -void colorplus_recalctimings(colorplus_t *colorplus) -{ - cga_recalctimings(&colorplus->cga); -} - -void colorplus_poll(void *p) -{ - colorplus_t *colorplus = (colorplus_t *)p; - int x, c; - int oldvc; - uint16_t dat0, dat1; - int cols[4]; - int col; - int oldsc; - static const int cols16[16] = { 0x10,0x12,0x14,0x16, - 0x18,0x1A,0x1C,0x1E, - 0x11,0x13,0x15,0x17, - 0x19,0x1B,0x1D,0x1F }; - uint8_t *plane0 = colorplus->cga.vram; - uint8_t *plane1 = colorplus->cga.vram + 0x4000; - - /* If one of the extra modes is not selected, drop down to the CGA - * drawing code. */ - if (!((colorplus->control & COLORPLUS_EITHER_MODE) && - (colorplus->cga.cgamode & CGA_GRAPHICS_MODE))) - { - cga_poll(&colorplus->cga); - return; - } - - if (!colorplus->cga.linepos) - { - colorplus->cga.vidtime += colorplus->cga.dispofftime; - colorplus->cga.cgastat |= 1; - colorplus->cga.linepos = 1; - oldsc = colorplus->cga.sc; - if ((colorplus->cga.crtc[8] & 3) == 3) - colorplus->cga.sc = ((colorplus->cga.sc << 1) + colorplus->cga.oddeven) & 7; - if (colorplus->cga.cgadispon) - { - if (colorplus->cga.displine < colorplus->cga.firstline) - { - colorplus->cga.firstline = colorplus->cga.displine; - video_wait_for_buffer(); - } - colorplus->cga.lastline = colorplus->cga.displine; - /* Left / right border */ - for (c = 0; c < 8; c++) - { - buffer->line[colorplus->cga.displine][c] = - buffer->line[colorplus->cga.displine][c + (colorplus->cga.crtc[1] << 4) + 8] = (colorplus->cga.cgacol & 15) + 16; - } - if (colorplus->control & COLORPLUS_320x200_MODE) - { - for (x = 0; x < colorplus->cga.crtc[1]; x++) - { - dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | - plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | - plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - colorplus->cga.ma++; - for (c = 0; c < 8; c++) - { - buffer->line[colorplus->cga.displine][(x << 4) + (c << 1) + 8] = - buffer->line[colorplus->cga.displine][(x << 4) + (c << 1) + 1 + 8] = - cols16[(dat0 >> 14) | ((dat1 >> 14) << 2)]; - dat0 <<= 2; - dat1 <<= 2; - } - } - } - else if (colorplus->control & COLORPLUS_640x200_MODE) - { - cols[0] = (colorplus->cga.cgacol & 15) | 16; - col = (colorplus->cga.cgacol & 16) ? 24 : 16; - if (colorplus->cga.cgamode & 4) - { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; - } - else if (colorplus->cga.cgacol & 32) - { - cols[1] = col | 3; - cols[2] = col | 5; - cols[3] = col | 7; - } - else - { - cols[1] = col | 2; - cols[2] = col | 4; - cols[3] = col | 6; - } - for (x = 0; x < colorplus->cga.crtc[1]; x++) - { - dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | - plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | - plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - colorplus->cga.ma++; - for (c = 0; c < 16; c++) - { - buffer->line[colorplus->cga.displine][(x << 4) + c + 8] = - cols[(dat0 >> 15) | ((dat1 >> 15) << 1)]; - dat0 <<= 1; - dat1 <<= 1; - } - } - } - } - else /* Top / bottom border */ - { - cols[0] = (colorplus->cga.cgacol & 15) + 16; - hline(buffer, 0, colorplus->cga.displine, (colorplus->cga.crtc[1] << 4) + 16, cols[0]); - } - - x = (colorplus->cga.crtc[1] << 4) + 16; - - if (colorplus->cga.composite) - { - for (c = 0; c < x; c++) - buffer32->line[colorplus->cga.displine][c] = buffer->line[colorplus->cga.displine][c] & 0xf; - - Composite_Process(colorplus->cga.cgamode, 0, x >> 2, buffer32->line[colorplus->cga.displine]); - } - - colorplus->cga.sc = oldsc; - if (colorplus->cga.vc == colorplus->cga.crtc[7] && !colorplus->cga.sc) - colorplus->cga.cgastat |= 8; - colorplus->cga.displine++; - if (colorplus->cga.displine >= 360) - colorplus->cga.displine = 0; - } - else - { - colorplus->cga.vidtime += colorplus->cga.dispontime; - colorplus->cga.linepos = 0; - if (colorplus->cga.vsynctime) - { - colorplus->cga.vsynctime--; - if (!colorplus->cga.vsynctime) - colorplus->cga.cgastat &= ~8; - } - if (colorplus->cga.sc == (colorplus->cga.crtc[11] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[11] & 31) >> 1))) - { - colorplus->cga.con = 0; - colorplus->cga.coff = 1; - } - if ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == (colorplus->cga.crtc[9] >> 1)) - colorplus->cga.maback = colorplus->cga.ma; - if (colorplus->cga.vadj) - { - colorplus->cga.sc++; - colorplus->cga.sc &= 31; - colorplus->cga.ma = colorplus->cga.maback; - colorplus->cga.vadj--; - if (!colorplus->cga.vadj) - { - colorplus->cga.cgadispon = 1; - colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff; - colorplus->cga.sc = 0; - } - } - else if (colorplus->cga.sc == colorplus->cga.crtc[9]) - { - colorplus->cga.maback = colorplus->cga.ma; - colorplus->cga.sc = 0; - oldvc = colorplus->cga.vc; - colorplus->cga.vc++; - colorplus->cga.vc &= 127; - - if (colorplus->cga.vc == colorplus->cga.crtc[6]) - colorplus->cga.cgadispon = 0; - - if (oldvc == colorplus->cga.crtc[4]) - { - colorplus->cga.vc = 0; - colorplus->cga.vadj = colorplus->cga.crtc[5]; - if (!colorplus->cga.vadj) colorplus->cga.cgadispon = 1; - if (!colorplus->cga.vadj) colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff; - if ((colorplus->cga.crtc[10] & 0x60) == 0x20) colorplus->cga.cursoron = 0; - else colorplus->cga.cursoron = colorplus->cga.cgablink & 8; - } - - if (colorplus->cga.vc == colorplus->cga.crtc[7]) - { - colorplus->cga.cgadispon = 0; - colorplus->cga.displine = 0; - colorplus->cga.vsynctime = 16; - if (colorplus->cga.crtc[7]) - { - if (colorplus->cga.cgamode & 1) x = (colorplus->cga.crtc[1] << 3) + 16; - else x = (colorplus->cga.crtc[1] << 4) + 16; - colorplus->cga.lastline++; - if (x != xsize || (colorplus->cga.lastline - colorplus->cga.firstline) != ysize) - { - xsize = x; - ysize = colorplus->cga.lastline - colorplus->cga.firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, (ysize << 1) + 16); - } - - if (colorplus->cga.composite) - video_blit_memtoscreen(0, colorplus->cga.firstline - 4, 0, (colorplus->cga.lastline - colorplus->cga.firstline) + 8, xsize, (colorplus->cga.lastline - colorplus->cga.firstline) + 8); - else - video_blit_memtoscreen_8(0, colorplus->cga.firstline - 4, 0, (colorplus->cga.lastline - colorplus->cga.firstline) + 8, xsize, (colorplus->cga.lastline - colorplus->cga.firstline) + 8); - frames++; - - video_res_x = xsize - 16; - video_res_y = ysize; - if (colorplus->cga.cgamode & 1) - { - video_res_x /= 8; - video_res_y /= colorplus->cga.crtc[9] + 1; - video_bpp = 0; - } - else if (!(colorplus->cga.cgamode & 2)) - { - video_res_x /= 16; - video_res_y /= colorplus->cga.crtc[9] + 1; - video_bpp = 0; - } - else if (!(colorplus->cga.cgamode & 16)) - { - video_res_x /= 2; - video_bpp = 2; - } - else - { - video_bpp = 1; - } - } - colorplus->cga.firstline = 1000; - colorplus->cga.lastline = 0; - colorplus->cga.cgablink++; - colorplus->cga.oddeven ^= 1; - } - } - else - { - colorplus->cga.sc++; - colorplus->cga.sc &= 31; - colorplus->cga.ma = colorplus->cga.maback; - } - if (colorplus->cga.cgadispon) - colorplus->cga.cgastat &= ~1; - if ((colorplus->cga.sc == (colorplus->cga.crtc[10] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[10] & 31) >> 1)))) - colorplus->cga.con = 1; - if (colorplus->cga.cgadispon && (colorplus->cga.cgamode & 1)) - { - for (x = 0; x < (colorplus->cga.crtc[1] << 1); x++) - colorplus->cga.charbuffer[x] = colorplus->cga.vram[(((colorplus->cga.ma << 1) + x) & 0x3fff)]; - } - } -} - -void colorplus_init(colorplus_t *colorplus) -{ - cga_init(&colorplus->cga); -} - -void *colorplus_standalone_init(const device_t *info) -{ - int display_type; - - colorplus_t *colorplus = malloc(sizeof(colorplus_t)); - memset(colorplus, 0, sizeof(colorplus_t)); - - /* Copied from the CGA init. Ideally this would be done by - * calling a helper function rather than duplicating code */ - display_type = device_get_config_int("display_type"); - colorplus->cga.composite = (display_type != CGA_RGB); - colorplus->cga.revision = device_get_config_int("composite_type"); - colorplus->cga.snow_enabled = device_get_config_int("snow_enabled"); - - colorplus->cga.vram = malloc(0x8000); - - cga_comp_init(1); - timer_add(colorplus_poll, &colorplus->cga.vidtime, TIMER_ALWAYS_ENABLED, colorplus); - mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, colorplus); - io_sethandler(0x03d0, 0x0010, colorplus_in, NULL, NULL, colorplus_out, NULL, NULL, colorplus); - - lpt3_init(0x3BC); - - return colorplus; -} - -void colorplus_close(void *p) -{ - colorplus_t *colorplus = (colorplus_t *)p; - - free(colorplus->cga.vram); - free(colorplus); -} - -void colorplus_speed_changed(void *p) -{ - colorplus_t *colorplus = (colorplus_t *)p; - - cga_recalctimings(&colorplus->cga); -} - -static const device_config_t colorplus_config[] = -{ - { - "display_type", "Display type", CONFIG_SELECTION, "", CGA_RGB, - { - { - "RGB", CGA_RGB - }, - { - "Composite", CGA_COMPOSITE - }, - { - "" - } - } - }, - { - "composite_type", "Composite type", CONFIG_SELECTION, "", COMPOSITE_OLD, - { - { - "Old", COMPOSITE_OLD - }, - { - "New", COMPOSITE_NEW - }, - { - "" - } - } - }, - { - "snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } -}; - -const device_t colorplus_device = -{ - "Colorplus", - DEVICE_ISA, 0, - colorplus_standalone_init, - colorplus_close, - NULL, NULL, - colorplus_speed_changed, - NULL, - colorplus_config -}; diff --git a/backup code/video - Cópia/vid_colorplus.h b/backup code/video - Cópia/vid_colorplus.h deleted file mode 100644 index 07a96ff4f..000000000 --- a/backup code/video - Cópia/vid_colorplus.h +++ /dev/null @@ -1,15 +0,0 @@ -typedef struct colorplus_t -{ - cga_t cga; - uint8_t control; -} colorplus_t; - -void colorplus_init(colorplus_t *colorplus); -void colorplus_out(uint16_t addr, uint8_t val, void *p); -uint8_t colorplus_in(uint16_t addr, void *p); -void colorplus_write(uint32_t addr, uint8_t val, void *p); -uint8_t colorplus_read(uint32_t addr, void *p); -void colorplus_recalctimings(colorplus_t *colorplus); -void colorplus_poll(void *p); - -extern const device_t colorplus_device; diff --git a/backup code/video - Cópia/vid_compaq_cga.c b/backup code/video - Cópia/vid_compaq_cga.c deleted file mode 100644 index c502aa6dd..000000000 --- a/backup code/video - Cópia/vid_compaq_cga.c +++ /dev/null @@ -1,461 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "video.h" -#include "vid_cga.h" -#include "vid_cga_comp.h" - -#define CGA_RGB 0 -#define CGA_COMPOSITE 1 - -typedef struct compaq_cga_t -{ - cga_t cga; - uint32_t flags; -} compaq_cga_t; - -static uint8_t mdaattr[256][2][2]; - -void compaq_cga_recalctimings(compaq_cga_t *self) -{ - double _dispontime, _dispofftime, disptime; - disptime = self->cga.crtc[0] + 1; - _dispontime = self->cga.crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - self->cga.dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - self->cga.dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); -} - -void compaq_cga_poll(void *p) -{ - compaq_cga_t *self = (compaq_cga_t *)p; - uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - uint32_t cols[4]; - int oldsc; - int underline = 0; - int blink = 0; - - /* If in graphics mode or character height is not 13, behave as CGA */ - if ((self->cga.cgamode & 0x12) || (self->cga.crtc[9] != 13)) - { - overscan_x = overscan_y = 16; - cga_poll(&self->cga); - return; - } else - overscan_x = overscan_y = 0; - -/* We are in Compaq 350-line CGA territory */ - if (!self->cga.linepos) - { - self->cga.vidtime += self->cga.dispofftime; - self->cga.cgastat |= 1; - self->cga.linepos = 1; - oldsc = self->cga.sc; - if ((self->cga.crtc[8] & 3) == 3) - self->cga.sc = ((self->cga.sc << 1) + self->cga.oddeven) & 7; - if (self->cga.cgadispon) - { - if (self->cga.displine < self->cga.firstline) - { - self->cga.firstline = self->cga.displine; - video_wait_for_buffer(); -// printf("Firstline %i\n",firstline); - } - self->cga.lastline = self->cga.displine; - - cols[0] = (self->cga.cgacol & 15); - - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[self->cga.displine])[c] = cols[0]; - if (self->cga.cgamode & 1) - ((uint32_t *)buffer32->line[self->cga.displine])[c + (self->cga.crtc[1] << 3) + 8] = cols[0]; - else - ((uint32_t *)buffer32->line[self->cga.displine])[c + (self->cga.crtc[1] << 4) + 8] = cols[0]; - } - if (self->cga.cgamode & 1) - { - for (x = 0; x < self->cga.crtc[1]; x++) - { - chr = self->cga.charbuffer[x << 1]; - attr = self->cga.charbuffer[(x << 1) + 1]; - drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); - if (self->flags) { - underline = 0; - blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - } - if (self->flags && (self->cga.cgamode & 0x80)) - { - cols[0] = mdaattr[attr][blink][0]; - cols[1] = mdaattr[attr][blink][1]; - if (self->cga.sc == 12 && (attr & 7) == 1) underline = 1; - } - else if (self->cga.cgamode & 0x20) - { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; - if (self->flags) { - if (blink) - cols[1] = cols[0]; - } else { - if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) - cols[1] = cols[0]; - } - } - else - { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; - } - if (self->flags && underline) - { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 3) + c + 8] = mdaattr[attr][blink][1]; - } - else if (drawcursor) - { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - } - else - { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; - } - self->cga.ma++; - } - } - else - { - for (x = 0; x < self->cga.crtc[1]; x++) - { - chr = self->cga.vram[((self->cga.ma << 1) & 0x3fff)]; - attr = self->cga.vram[(((self->cga.ma << 1) + 1) & 0x3fff)]; - drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); - if (self->flags) { - underline = 0; - blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - } - if (self->flags && (self->cga.cgamode & 0x80)) - { - cols[0] = mdaattr[attr][blink][0]; - cols[1] = mdaattr[attr][blink][1]; - if (self->cga.sc == 12 && (attr & 7) == 1) underline = 1; - } - else if (self->cga.cgamode & 0x20) - { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; - if (self->flags) { - if (blink) - cols[1] = cols[0]; - } else { - if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) - cols[1] = cols[0]; - } - } - else - { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; - } - self->cga.ma++; - if (self->flags && underline) - { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4)+(c << 1) + 8] = - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4)+(c << 1) + 9] = mdaattr[attr][blink][1]; - } - else if (drawcursor) - { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4)+(c << 1) + 8] = - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } - else - { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } - } - else - { - cols[0] = (self->cga.cgacol & 15) + 16; - if (self->cga.cgamode & 1) hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 3) + 16, cols[0]); - else hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 4) + 16, cols[0]); - } - - if (self->cga.cgamode & 1) x = (self->cga.crtc[1] << 3) + 16; - else x = (self->cga.crtc[1] << 4) + 16; - - if (self->cga.composite) - { - for (c = 0; c < x; c++) - buffer32->line[self->cga.displine][c] = ((uint32_t *)buffer32->line[self->cga.displine])[c] & 0xf; - - if (self->flags) - Composite_Process(self->cga.cgamode & 0x7F, 0, x >> 2, buffer32->line[self->cga.displine]); - else - Composite_Process(self->cga.cgamode, 0, x >> 2, buffer32->line[self->cga.displine]); - } - else - { - for (c = 0; c < x; c++) - buffer->line[self->cga.displine][c] = ((uint32_t *)buffer32->line[self->cga.displine])[c]; - } - - self->cga.sc = oldsc; - if (self->cga.vc == self->cga.crtc[7] && !self->cga.sc) - self->cga.cgastat |= 8; - self->cga.displine++; - if (self->cga.displine >= 500) - self->cga.displine = 0; - } - else - { - self->cga.vidtime += self->cga.dispontime; - self->cga.linepos = 0; - if (self->cga.vsynctime) - { - self->cga.vsynctime--; - if (!self->cga.vsynctime) - self->cga.cgastat &= ~8; - } - if (self->cga.sc == (self->cga.crtc[11] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[11] & 31) >> 1))) - { - self->cga.con = 0; - self->cga.coff = 1; - } - if ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == (self->cga.crtc[9] >> 1)) - self->cga.maback = self->cga.ma; - if (self->cga.vadj) - { - self->cga.sc++; - self->cga.sc &= 31; - self->cga.ma = self->cga.maback; - self->cga.vadj--; - if (!self->cga.vadj) - { - self->cga.cgadispon = 1; - self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; - self->cga.sc = 0; - } - } - else if (self->cga.sc == self->cga.crtc[9]) - { - self->cga.maback = self->cga.ma; - self->cga.sc = 0; - oldvc = self->cga.vc; - self->cga.vc++; - self->cga.vc &= 127; - - if (self->cga.vc == self->cga.crtc[6]) - self->cga.cgadispon = 0; - - if (oldvc == self->cga.crtc[4]) - { - self->cga.vc = 0; - self->cga.vadj = self->cga.crtc[5]; - if (!self->cga.vadj) self->cga.cgadispon = 1; - if (!self->cga.vadj) self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; - if ((self->cga.crtc[10] & 0x60) == 0x20) self->cga.cursoron = 0; - else self->cga.cursoron = self->cga.cgablink & 8; - } - - if (self->cga.vc == self->cga.crtc[7]) - { - self->cga.cgadispon = 0; - self->cga.displine = 0; - self->cga.vsynctime = 16; - if (self->cga.crtc[7]) - { -// printf("Lastline %i Firstline %i %i\n",self->cga.lastline,self->cga.firstline,self->cga.lastline-self->cga.firstline); - - if (self->cga.cgamode & 1) x = (self->cga.crtc[1] << 3); - else x = (self->cga.crtc[1] << 4); - self->cga.lastline++; - if (x != xsize || (self->cga.lastline - self->cga.firstline) != ysize) - { - xsize = x; - ysize = self->cga.lastline - self->cga.firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,self->cga.crtc[1]); - - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); - } - - if (self->cga.composite) - video_blit_memtoscreen(8, self->cga.firstline, 0, ysize, xsize, ysize); - else - video_blit_memtoscreen_8(8, self->cga.firstline, 0, ysize, xsize, ysize); - frames++; - - video_res_x = xsize - 16; - video_res_y = ysize; - if (self->cga.cgamode & 1) - { - video_res_x /= 8; - video_res_y /= self->cga.crtc[9] + 1; - video_bpp = 0; - } - else if (!(self->cga.cgamode & 2)) - { - video_res_x /= 16; - video_res_y /= self->cga.crtc[9] + 1; - video_bpp = 0; - } - else if (!(self->cga.cgamode & 16)) - { - video_res_x /= 2; - video_bpp = 2; - } - else - { - video_bpp = 1; - } - } - self->cga.firstline = 1000; - self->cga.lastline = 0; - self->cga.cgablink++; - self->cga.oddeven ^= 1; - } - } - else - { - self->cga.sc++; - self->cga.sc &= 31; - self->cga.ma = self->cga.maback; - } - if (self->cga.cgadispon) - self->cga.cgastat &= ~1; - if ((self->cga.sc == (self->cga.crtc[10] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[10] & 31) >> 1)))) - self->cga.con = 1; - if (self->cga.cgadispon && (self->cga.cgamode & 1)) - { - for (x = 0; x < (self->cga.crtc[1] << 1); x++) - self->cga.charbuffer[x] = self->cga.vram[(((self->cga.ma << 1) + x) & 0x3fff)]; - } - } - -} - -void *compaq_cga_init(const device_t *info) -{ - int display_type; - int c; - compaq_cga_t *self = malloc(sizeof(compaq_cga_t)); - memset(self, 0, sizeof(compaq_cga_t)); - - display_type = device_get_config_int("display_type"); - self->cga.composite = (display_type != CGA_RGB); - self->cga.revision = device_get_config_int("composite_type"); - self->cga.snow_enabled = device_get_config_int("snow_enabled"); - - self->cga.vram = malloc(0x4000); - - cga_comp_init(self->cga.revision); - timer_add(compaq_cga_poll, &self->cga.vidtime, TIMER_ALWAYS_ENABLED, self); - mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, self); - io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, self); - - if (info->local) { - for (c = 0; c < 256; c++) { - mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16; - if (c & 8) mdaattr[c][0][1] = 15 + 16; - else mdaattr[c][0][1] = 7 + 16; - } - mdaattr[0x70][0][1] = 16; - mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15; - mdaattr[0xF0][0][1] = 16; - mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15; - mdaattr[0x78][0][1] = 16 + 7; - mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15; - mdaattr[0xF8][0][1] = 16 + 7; - mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15; - mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16; - mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16; - mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16; - mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16; - } - - self->flags = info->local; - - overscan_x = overscan_y = 16; - - self->cga.rgb_type = device_get_config_int("rgb_type"); - cga_palette = (self->cga.rgb_type << 1); - cgapal_rebuild(); - - return self; -} - -void compaq_cga_close(void *p) -{ - compaq_cga_t *self = (compaq_cga_t *)p; - - free(self->cga.vram); - free(self); -} - -void compaq_cga_speed_changed(void *p) -{ - compaq_cga_t *self = (compaq_cga_t *)p; - - if (self->cga.crtc[9] == 13) /* Character height */ - { - compaq_cga_recalctimings(self); - } - else - { - cga_recalctimings(&self->cga); - } -} - -extern const device_config_t cga_config[]; - -const device_t compaq_cga_device = -{ - "Compaq CGA", - DEVICE_ISA, 0, - compaq_cga_init, - compaq_cga_close, - NULL, - NULL, - compaq_cga_speed_changed, - NULL, - cga_config -}; - -const device_t compaq_cga_2_device = -{ - "Compaq CGA 2", - DEVICE_ISA, 1, - compaq_cga_init, - compaq_cga_close, - NULL, - NULL, - compaq_cga_speed_changed, - NULL, - cga_config -}; diff --git a/backup code/video - Cópia/vid_compaq_cga.h b/backup code/video - Cópia/vid_compaq_cga.h deleted file mode 100644 index e6c684d52..000000000 --- a/backup code/video - Cópia/vid_compaq_cga.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef VIDEO_COMPAQ_CGA_H -# define VIDEO_COMPAQ_CGA_H - - -#ifdef EMU_DEVICE_H -extern const device_t compaq_cga_device; -extern const device_t compaq_cga_2_device; -#endif - - -#endif /*VIDEO_COMPAQ_CGA_H*/ diff --git a/backup code/video - Cópia/vid_ega.c b/backup code/video - Cópia/vid_ega.c deleted file mode 100644 index 426d23957..000000000 --- a/backup code/video - Cópia/vid_ega.c +++ /dev/null @@ -1,1293 +0,0 @@ -/* - * 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 EGA, Chips & Technologies SuperEGA, and - * AX JEGA graphics cards. - * - * Version: @(#)vid_ega.c 1.0.17 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * akm - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "video.h" -#include "vid_ega.h" -#include "vid_ega_render.h" - - -#define BIOS_IBM_PATH L"roms/video/ega/ibm_6277356_ega_card_u44_27128.bin" -#define BIOS_CPQ_PATH L"roms/video/ega/108281-001.bin" -#define BIOS_SEGA_PATH L"roms/video/ega/lega.vbi" - - -enum { - EGA_IBM = 0, - EGA_COMPAQ, - EGA_SUPEREGA -}; - - -extern uint8_t edatlookup[4][4]; - -static uint8_t ega_rotate[8][256]; - -static uint32_t pallook16[256], pallook64[256]; - -/*3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour)*/ -int egaswitchread,egaswitches=9; /*7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines)*/ - -static int old_overscan_color = 0; - -int update_overscan = 0; - -#ifdef JEGA -uint8_t jfont_sbcs_19[SBCS19_LEN]; /* 256 * 19( * 8) */ -uint8_t jfont_dbcs_16[DBCS16_LEN]; /* 65536 * 16 * 2 (* 8) */ - -typedef struct { - char id[ID_LEN]; - char name[NAME_LEN]; - unsigned char width; - unsigned char height; - unsigned char type; -} fontx_h; - -typedef struct { - uint16_t start; - uint16_t end; -} fontxTbl; - -static __inline int ega_jega_enabled(ega_t *ega) -{ - if (!ega->is_jega) - { - return 0; - } - - return !(ega->RMOD1 & 0x40); -} - -void ega_jega_write_font(ega_t *ega) -{ - unsigned int chr = ega->RDFFB; - unsigned int chr_2 = ega->RDFSB; - - ega->RSTAT &= ~0x02; - - /* Check if the character code is in the Wide character set of Shift-JIS */ - if (((chr >= 0x40) && (chr <= 0x7e)) || ((chr >= 0x80) && (chr <= 0xfc))) - { - if (ega->font_index >= 32) - { - ega->font_index = 0; - } - chr <<= 8; - /* Fix vertical character position */ - chr |= chr_2; - if (ega->font_index < 16) - { - jfont_dbcs_16[(chr * 32) + (ega->font_index * 2)] = ega->RDFAP; /* 16x16 font */ - } - else - { - jfont_dbcs_16[(chr * 32) + ((ega->font_index - 16) * 2) + 1] = ega->RDFAP; /* 16x16 font */ - } - } - else - { - if (ega->font_index >= 19) - { - ega->font_index = 0; - } - jfont_sbcs_19[(chr * 19) + ega->font_index] = ega->RDFAP; /* 8x19 font */ - } - ega->font_index++; - ega->RSTAT |= 0x02; -} - -void ega_jega_read_font(ega_t *ega) -{ - unsigned int chr = ega->RDFFB; - unsigned int chr_2 = ega->RDFSB; - - ega->RSTAT &= ~0x02; - - /* Check if the character code is in the Wide character set of Shift-JIS */ - if (((chr >= 0x40) && (chr <= 0x7e)) || ((chr >= 0x80) && (chr <= 0xfc))) - { - if (ega->font_index >= 32) - { - ega->font_index = 0; - } - chr <<= 8; - /* Fix vertical character position */ - chr |= chr_2; - if (ega->font_index < 16) - { - ega->RDFAP = jfont_dbcs_16[(chr * 32) + (ega->font_index * 2)]; /* 16x16 font */ - } - else - { - ega->RDFAP = jfont_dbcs_16[(chr * 32) + ((ega->font_index - 16) * 2) + 1]; /* 16x16 font */ - } - } - else - { - if (ega->font_index >= 19) - { - ega->font_index = 0; - } - ega->RDFAP = jfont_sbcs_19[(chr * 19) + ega->font_index]; /* 8x19 font */ - } - ega->font_index++; - ega->RSTAT |= 0x02; -} -#endif - - -void ega_out(uint16_t addr, uint8_t val, void *p) -{ - ega_t *ega = (ega_t *)p; - int c; - uint8_t o, old; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3c0: - case 0x3c1: - if (!ega->attrff) - ega->attraddr = val & 31; - else - { - ega->attrregs[ega->attraddr & 31] = val; - if (ega->attraddr < 16) - fullchange = changeframecount; - if (ega->attraddr == 0x10 || ega->attraddr == 0x14 || ega->attraddr < 0x10) - { - for (c = 0; c < 16; c++) - { - if (ega->attrregs[0x10] & 0x80) ega->egapal[c] = (ega->attrregs[c] & 0xf) | ((ega->attrregs[0x14] & 0xf) << 4); - else ega->egapal[c] = (ega->attrregs[c] & 0x3f) | ((ega->attrregs[0x14] & 0xc) << 4); - } - } - } - ega->attrff ^= 1; - break; - case 0x3c2: - egaswitchread = val & 0xc; - ega->vres = !(val & 0x80); - ega->pallook = ega->vres ? pallook16 : pallook64; - ega->vidclock = val & 4; /*printf("3C2 write %02X\n",val);*/ - ega->miscout=val; - break; - case 0x3c4: - ega->seqaddr = val; - break; - case 0x3c5: - o = ega->seqregs[ega->seqaddr & 0xf]; - ega->seqregs[ega->seqaddr & 0xf] = val; - if (o != val && (ega->seqaddr & 0xf) == 1) - ega_recalctimings(ega); - switch (ega->seqaddr & 0xf) - { - case 1: - if (ega->scrblank && !(val & 0x20)) - fullchange = 3; - ega->scrblank = (ega->scrblank & ~0x20) | (val & 0x20); - break; - case 2: - ega->writemask = val & 0xf; - break; - case 3: - ega->charsetb = (((val >> 2) & 3) * 0x10000) + 2; - ega->charseta = ((val & 3) * 0x10000) + 2; - break; - case 4: - ega->chain2_write = !(val & 4); - break; - } - break; - case 0x3ce: - ega->gdcaddr = val; - break; - case 0x3cf: - ega->gdcreg[ega->gdcaddr & 15] = val; - switch (ega->gdcaddr & 15) - { - case 2: - ega->colourcompare = val; - break; - case 4: - ega->readplane = val & 3; - break; - case 5: - ega->writemode = val & 3; - ega->readmode = val & 8; - ega->chain2_read = val & 0x10; - break; - case 6: - switch (val & 0xc) - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&ega->mapping, 0xa0000, 0x20000); - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&ega->mapping, 0xa0000, 0x10000); - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&ega->mapping, 0xb0000, 0x08000); - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&ega->mapping, 0xb8000, 0x08000); - break; - } - break; - case 7: - ega->colournocare = val; - break; - } - break; - case 0x3d0: - case 0x3d4: - ega->crtcreg = val & 31; - return; - case 0x3d1: - case 0x3d5: - if (ega->crtcreg <= 7 && ega->crtc[0x11] & 0x80) return; - old = ega->crtc[ega->crtcreg]; - ega->crtc[ega->crtcreg] = val; - if (old != val) - { - if (ega->crtcreg < 0xe || ega->crtcreg > 0x10) - { - fullchange = changeframecount; - ega_recalctimings(ega); - } - } - break; - } -} - -uint8_t ega_in(uint16_t addr, void *p) -{ - ega_t *ega = (ega_t *)p; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3c0: - return ega->attraddr; - case 0x3c1: - return ega->attrregs[ega->attraddr]; - case 0x3c2: - switch (egaswitchread) - { - case 0xc: return (egaswitches & 1) ? 0x10 : 0; - case 0x8: return (egaswitches & 2) ? 0x10 : 0; - case 0x4: return (egaswitches & 4) ? 0x10 : 0; - case 0x0: return (egaswitches & 8) ? 0x10 : 0; - } - break; - case 0x3c4: - return ega->seqaddr; - case 0x3c5: - return ega->seqregs[ega->seqaddr & 0xf]; - case 0x3c8: - return 2; - case 0x3cc: - return ega->miscout; - case 0x3ce: - return ega->gdcaddr; - case 0x3cf: - return ega->gdcreg[ega->gdcaddr & 0xf]; - case 0x3d0: - case 0x3d4: - return ega->crtcreg; - case 0x3d1: - case 0x3d5: - return ega->crtc[ega->crtcreg]; - case 0x3da: - ega->attrff = 0; - ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ - return ega->stat; - } - return 0xff; -} - - -void ega_recalctimings(ega_t *ega) -{ - double _dispontime, _dispofftime, disptime; - double crtcconst; - - ega->vtotal = ega->crtc[6]; - ega->dispend = ega->crtc[0x12]; - ega->vsyncstart = ega->crtc[0x10]; - ega->split = ega->crtc[0x18]; - - if (ega->crtc[7] & 1) ega->vtotal |= 0x100; - if (ega->crtc[7] & 32) ega->vtotal |= 0x200; - ega->vtotal += 2; - - if (ega->crtc[7] & 2) ega->dispend |= 0x100; - if (ega->crtc[7] & 64) ega->dispend |= 0x200; - ega->dispend++; - - if (ega->crtc[7] & 4) ega->vsyncstart |= 0x100; - if (ega->crtc[7] & 128) ega->vsyncstart |= 0x200; - ega->vsyncstart++; - - if (ega->crtc[7] & 0x10) ega->split |= 0x100; - if (ega->crtc[9] & 0x40) ega->split |= 0x200; - ega->split++; - - ega->hdisp = ega->crtc[1]; - ega->hdisp++; - - ega->rowoffset = ega->crtc[0x13]; - ega->rowcount = ega->crtc[9] & 0x1f; - overscan_y = (ega->rowcount + 1) << 1; - - if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); - else crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); - - if (ega->seqregs[1] & 8) - { - disptime = (double) ((ega->crtc[0] + 2) << 1); - _dispontime = (double) ((ega->crtc[1] + 1) << 1); - - overscan_y <<= 1; - } else { - disptime = (double) (ega->crtc[0] + 2); - _dispontime = (double) (ega->crtc[1] + 1); - } - if (overscan_y < 16) - { - overscan_y = 16; - } - _dispofftime = disptime - _dispontime; - _dispontime = _dispontime * crtcconst; - _dispofftime = _dispofftime * crtcconst; - - ega->dispontime = (int64_t)(_dispontime * (1LL << TIMER_SHIFT)); - ega->dispofftime = (int64_t)(_dispofftime * (1LL << TIMER_SHIFT)); -} - - -void ega_poll(void *p) -{ - ega_t *ega = (ega_t *)p; - int x; - int drawcursor = 0; - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - int y_add_ex = enable_overscan ? overscan_y : 0; - int x_add_ex = enable_overscan ? 16 : 0; - uint32_t *q, i, j; - int wx = 640, wy = 350; - - if (!ega->linepos) - { - ega->vidtime += ega->dispofftime; - - ega->stat |= 1; - ega->linepos = 1; - - if (ega->dispon) - { - if (ega->firstline == 2000) - { - ega->firstline = ega->displine; - video_wait_for_buffer(); - } - - if (ega->scrblank) - { - ega_render_blank(ega); - } - else if (!(ega->gdcreg[6] & 1)) - { - if (fullchange) - { -#ifdef JEGA - if (ega_jega_enabled(ega)) - { - ega_render_text_jega(ega, drawcursor); - } - else - { - ega_render_text_standard(ega, drawcursor); - } -#else - ega_render_text_standard(ega, drawcursor); -#endif - } - } - else - { - switch (ega->gdcreg[5] & 0x20) - { - case 0x00: - if (ega->seqregs[1] & 8) - { - ega_render_4bpp_lowres(ega); - } - else - { - ega_render_4bpp_highres(ega); - } - break; - case 0x20: - ega_render_2bpp(ega); - break; - } - } - if (ega->lastline < ega->displine) - ega->lastline = ega->displine; - } - - ega->displine++; - if (ega->interlace) - ega->displine++; - if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines) - ega->stat &= ~8; - ega->vslines++; - if (ega->displine > 500) - ega->displine = 0; - } - else - { - ega->vidtime += ega->dispontime; - if (ega->dispon) - ega->stat &= ~1; - ega->linepos = 0; - if (ega->sc == (ega->crtc[11] & 31)) - ega->con = 0; - if (ega->dispon) - { - if (ega->sc == (ega->crtc[9] & 31)) - { - ega->sc = 0; - if (ega->sc == (ega->crtc[11] & 31)) - ega->con = 0; - - ega->maback += (ega->rowoffset << 3); - if (ega->interlace) - ega->maback += (ega->rowoffset << 3); - ega->maback &= ega->vrammask; - ega->ma = ega->maback; - } - else - { - ega->sc++; - ega->sc &= 31; - ega->ma = ega->maback; - } - } - ega->vc++; - ega->vc &= 1023; - if (ega->vc == ega->split) - { - ega->ma = ega->maback = 0; - if (ega->attrregs[0x10] & 0x20) - ega->scrollcache = 0; - } - if (ega->vc == ega->dispend) - { - ega->dispon=0; - if (ega->crtc[10] & 0x20) ega->cursoron = 0; - else ega->cursoron = ega->blink & 16; - if (!(ega->gdcreg[6] & 1) && !(ega->blink & 15)) - fullchange = 2; - ega->blink++; - - if (fullchange) - fullchange--; - } - if (ega->vc == ega->vsyncstart) - { - ega->dispon = 0; - ega->stat |= 8; - if (ega->seqregs[1] & 8) x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9) * 2; - else x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9); - - if (ega->interlace && !ega->oddeven) ega->lastline++; - if (ega->interlace && ega->oddeven) ega->firstline--; - - if ((x != xsize || (ega->lastline - ega->firstline + 1) != ysize) || update_overscan || video_force_resize_get()) - { - xsize = x; - ysize = ega->lastline - ega->firstline + 1; - if (xsize < 64) xsize = 640; - if (ysize < 32) ysize = 200; - y_add = enable_overscan ? 14 : 0; - x_add = enable_overscan ? 8 : 0; - y_add_ex = enable_overscan ? 28 : 0; - x_add_ex = enable_overscan ? 16 : 0; - - if ((xsize > 2032) || ((ysize + y_add_ex) > 2048)) - { - x_add = x_add_ex = 0; - y_add = y_add_ex = 0; - suppress_overscan = 1; - } - else - { - suppress_overscan = 0; - } - - if (ega->vres) - set_screen_size(xsize + x_add_ex, (ysize << 1) + y_add_ex); - else - set_screen_size(xsize + x_add_ex, ysize + y_add_ex); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - - if (enable_overscan) - { - if ((x >= 160) && ((ega->lastline - ega->firstline) >= 120)) - { - /* Draw (overscan_size - scroll size) lines of overscan on top. */ - for (i = 0; i < (y_add - (ega->crtc[8] & 0x1f)); i++) - { - q = &((uint32_t *)buffer32->line[i & 0x7ff])[32]; - - for (j = 0; j < (xsize + x_add_ex); j++) - { - q[j] = ega->pallook[ega->attrregs[0x11]]; - } - } - - /* Draw (overscan_size + scroll size) lines of overscan on the bottom. */ - for (i = 0; i < (y_add + (ega->crtc[8] & 0x1f)); i++) - { - q = &((uint32_t *)buffer32->line[(ysize + y_add + i - (ega->crtc[8] & 0x1f)) & 0x7ff])[32]; - - for (j = 0; j < (xsize + x_add_ex); j++) - { - q[j] = ega->pallook[ega->attrregs[0x11]]; - } - } - - for (i = (y_add - (ega->crtc[8] & 0x1f)); i < (ysize + y_add - (ega->crtc[8] & 0x1f)); i ++) - { - q = &((uint32_t *)buffer32->line[(i - (ega->crtc[8] & 0x1f)) & 0x7ff])[32]; - - for (j = 0; j < x_add; j++) - { - q[j] = ega->pallook[ega->attrregs[0x11]]; - q[xsize + x_add + j] = ega->pallook[ega->attrregs[0x11]]; - } - } - } - } - else - { - if (ega->crtc[8] & 0x1f) - { - /* Draw (scroll size) lines of overscan on the bottom. */ - for (i = 0; i < (ega->crtc[8] & 0x1f); i++) - { - q = &((uint32_t *)buffer32->line[(ysize + i - (ega->crtc[8] & 0x1f)) & 0x7ff])[32]; - - for (j = 0; j < xsize; j++) - { - q[j] = ega->pallook[ega->attrregs[0x11]]; - } - } - } - } - - video_blit_memtoscreen(32, 0, ega->firstline, ega->lastline + 1 + y_add_ex, xsize + x_add_ex, ega->lastline - ega->firstline + 1 + y_add_ex); - - frames++; - - ega->video_res_x = wx; - ega->video_res_y = wy + 1; - if (!(ega->gdcreg[6] & 1)) /*Text mode*/ - { - ega->video_res_x /= (ega->seqregs[1] & 1) ? 8 : 9; - ega->video_res_y /= (ega->crtc[9] & 31) + 1; - ega->video_bpp = 0; - } - else - { - if (ega->crtc[9] & 0x80) - ega->video_res_y /= 2; - if (!(ega->crtc[0x17] & 1)) - ega->video_res_y *= 2; - ega->video_res_y /= (ega->crtc[9] & 31) + 1; - if (ega->seqregs[1] & 8) - ega->video_res_x /= 2; - ega->video_bpp = (ega->gdcreg[5] & 0x20) ? 2 : 4; - } - - ega->firstline = 2000; - ega->lastline = 0; - - ega->maback = ega->ma = (ega->crtc[0xc] << 8)| ega->crtc[0xd]; - ega->ca = (ega->crtc[0xe] << 8) | ega->crtc[0xf]; - ega->ma <<= 2; - ega->maback <<= 2; - ega->ca <<= 2; - changeframecount = 2; - ega->vslines = 0; - } - if (ega->vc == ega->vtotal) - { - ega->vc = 0; - ega->sc = 0; - ega->dispon = 1; - ega->displine = (ega->interlace && ega->oddeven) ? 1 : 0; - ega->scrollcache = ega->attrregs[0x13] & 7; - } - if (ega->sc == (ega->crtc[10] & 31)) - ega->con = 1; - } -} - - -void ega_write(uint32_t addr, uint8_t val, void *p) -{ - ega_t *ega = (ega_t *)p; - uint8_t vala, valb, valc, vald; - int writemask2 = ega->writemask; - - egawrites++; - cycles -= video_timing_write_b; - - if (addr >= 0xB0000) addr &= 0x7fff; - else addr &= 0xffff; - - if (ega->chain2_write) - { - writemask2 &= ~0xa; - if (addr & 1) - writemask2 <<= 1; - addr &= ~1; - if (addr & 0x4000) - addr |= 1; - addr &= ~0x4000; - } - - addr <<= 2; - - if (addr >= ega->vram_limit) - return; - - if (!(ega->gdcreg[6] & 1)) - fullchange = 2; - - switch (ega->writemode) - { - case 1: - if (writemask2 & 1) ega->vram[addr] = ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = ega->ld; - break; - case 0: - if (ega->gdcreg[3] & 7) - val = ega_rotate[ega->gdcreg[3] & 7][val]; - - if (ega->gdcreg[8] == 0xff && !(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1]) - { - if (writemask2 & 1) ega->vram[addr] = val; - if (writemask2 & 2) ega->vram[addr | 0x1] = val; - if (writemask2 & 4) ega->vram[addr | 0x2] = val; - if (writemask2 & 8) ega->vram[addr | 0x3] = val; - } - else - { - if (ega->gdcreg[1] & 1) vala = (ega->gdcreg[0] & 1) ? 0xff : 0; - else vala = val; - if (ega->gdcreg[1] & 2) valb = (ega->gdcreg[0] & 2) ? 0xff : 0; - else valb = val; - if (ega->gdcreg[1] & 4) valc = (ega->gdcreg[0] & 4) ? 0xff : 0; - else valc = val; - if (ega->gdcreg[1] & 8) vald = (ega->gdcreg[0] & 8) ? 0xff : 0; - else vald = val; - switch (ega->gdcreg[3] & 0x18) - { - case 0: /*Set*/ - if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; - break; - } - } - break; - case 2: - if (!(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1]) - { - if (writemask2 & 1) ega->vram[addr] = (((val & 1) ? 0xff : 0) & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); - if (writemask2 & 2) ega->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); - if (writemask2 & 4) ega->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); - if (writemask2 & 8) ega->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); - } - else - { - vala = ((val & 1) ? 0xff : 0); - valb = ((val & 2) ? 0xff : 0); - valc = ((val & 4) ? 0xff : 0); - vald = ((val & 8) ? 0xff : 0); - switch (ega->gdcreg[3] & 0x18) - { - case 0: /*Set*/ - if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; - break; - } - } - break; - } -} - - -uint8_t ega_read(uint32_t addr, void *p) -{ - ega_t *ega = (ega_t *)p; - uint8_t temp, temp2, temp3, temp4; - int readplane = ega->readplane; - - egareads++; - cycles -= video_timing_read_b; - if (addr >= 0xb0000) addr &= 0x7fff; - else addr &= 0xffff; - - if (ega->chain2_read) - { - readplane = (readplane & 2) | (addr & 1); - addr &= ~1; - if (addr & 0x4000) - addr |= 1; - addr &= ~0x4000; - } - - addr <<= 2; - - if (addr >= ega->vram_limit) - return 0xff; - - ega->la = ega->vram[addr]; - ega->lb = ega->vram[addr | 0x1]; - ega->lc = ega->vram[addr | 0x2]; - ega->ld = ega->vram[addr | 0x3]; - if (ega->readmode) - { - temp = ega->la; - temp ^= (ega->colourcompare & 1) ? 0xff : 0; - temp &= (ega->colournocare & 1) ? 0xff : 0; - temp2 = ega->lb; - temp2 ^= (ega->colourcompare & 2) ? 0xff : 0; - temp2 &= (ega->colournocare & 2) ? 0xff : 0; - temp3 = ega->lc; - temp3 ^= (ega->colourcompare & 4) ? 0xff : 0; - temp3 &= (ega->colournocare & 4) ? 0xff : 0; - temp4 = ega->ld; - temp4 ^= (ega->colourcompare & 8) ? 0xff : 0; - temp4 &= (ega->colournocare & 8) ? 0xff : 0; - return ~(temp | temp2 | temp3 | temp4); - } - return ega->vram[addr | readplane]; -} - - -void ega_init(ega_t *ega, int monitor_type, int is_mono) -{ - int c, d, e; - - ega->vram = malloc(0x40000); - ega->vrammask = 0x3ffff; - - for (c = 0; c < 256; c++) - { - e = c; - for (d = 0; d < 8; d++) - { - ega_rotate[d][c] = e; - e = (e >> 1) | ((e & 1) ? 0x80 : 0); - } - } - - for (c = 0; c < 4; c++) - { - for (d = 0; d < 4; d++) - { - edatlookup[c][d] = 0; - if (c & 1) edatlookup[c][d] |= 1; - if (d & 1) edatlookup[c][d] |= 2; - if (c & 2) edatlookup[c][d] |= 0x10; - if (d & 2) edatlookup[c][d] |= 0x20; - } - } - - if (is_mono) - { - for (c = 0; c < 256; c++) - { - switch (monitor_type >> 4) - { - case DISPLAY_GREEN: - switch ((c >> 3) & 3) - { - case 0: - pallook64[c] = pallook16[c] = makecol32(0, 0, 0); - break; - case 2: - pallook64[c] = pallook16[c] = makecol32(0x04, 0x8a, 0x20); - break; - case 1: - pallook64[c] = pallook16[c] = makecol32(0x08, 0xc7, 0x2c); - break; - case 3: - pallook64[c] = pallook16[c] = makecol32(0x34, 0xff, 0x5d); - break; - } - break; - case DISPLAY_AMBER: - switch ((c >> 3) & 3) - { - case 0: - pallook64[c] = pallook16[c] = makecol32(0, 0, 0); - break; - case 2: - pallook64[c] = pallook16[c] = makecol32(0xb2, 0x4d, 0x00); - break; - case 1: - pallook64[c] = pallook16[c] = makecol32(0xef, 0x79, 0x00); - break; - case 3: - pallook64[c] = pallook16[c] = makecol32(0xff, 0xe3, 0x34); - break; - } - break; - case DISPLAY_WHITE: default: - switch ((c >> 3) & 3) - { - case 0: - pallook64[c] = pallook16[c] = makecol32(0, 0, 0); - break; - case 2: - pallook64[c] = pallook16[c] = makecol32(0x7a, 0x81, 0x83); - break; - case 1: - pallook64[c] = pallook16[c] = makecol32(0xaf, 0xb3, 0xb0); - break; - case 3: - pallook64[c] = pallook16[c] = makecol32(0xff, 0xfd, 0xed); - break; - } - break; - } - } - } - else - { - for (c = 0; c < 256; c++) - { - pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - pallook64[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); - pallook16[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - pallook16[c] += makecol32(((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55); - if ((c & 0x17) == 6) - pallook16[c] = makecol32(0xaa, 0x55, 0); - } - } - ega->pallook = pallook16; - - egaswitches = monitor_type & 0xf; - - ega->vram_limit = 256 * 1024; - ega->vrammask = ega->vram_limit-1; - - old_overscan_color = 0; - - ega->miscout |= 0x22; - ega->oddeven_page = 0; - - ega->seqregs[4] |= 2; - ega->extvram = 1; - - update_overscan = 0; - - ega->crtc[0] = 63; - ega->crtc[6] = 255; - -#ifdef JEGA - ega->is_jega = 0; -#endif -} - - -static void *ega_standalone_init(const device_t *info) -{ - ega_t *ega = malloc(sizeof(ega_t)); - int monitor_type; - - memset(ega, 0, sizeof(ega_t)); - - overscan_x = 16; - overscan_y = 28; - - switch(info->local) { - case EGA_IBM: - default: - rom_init(&ega->bios_rom, BIOS_IBM_PATH, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - case EGA_COMPAQ: - rom_init(&ega->bios_rom, BIOS_CPQ_PATH, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - case EGA_SUPEREGA: - rom_init(&ega->bios_rom, BIOS_SEGA_PATH, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - } - - if (ega->bios_rom.rom[0x3ffe] == 0xaa && ega->bios_rom.rom[0x3fff] == 0x55) - { - int c; - - for (c = 0; c < 0x2000; c++) - { - uint8_t temp = ega->bios_rom.rom[c]; - ega->bios_rom.rom[c] = ega->bios_rom.rom[0x3fff - c]; - ega->bios_rom.rom[0x3fff - c] = temp; - } - } - - monitor_type = device_get_config_int("monitor_type"); - ega_init(ega, monitor_type, (monitor_type & 0xf) == 10); - - ega->vram_limit = device_get_config_int("memory") * 1024; - ega->vrammask = ega->vram_limit-1; - - mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); - timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); - io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - return ega; -} - -#ifdef JEGA -uint16_t chrtosht(FILE *fp) -{ - uint16_t i, j; - i = (uint8_t) getc(fp); - j = (uint8_t) getc(fp) << 8; - return (i | j); -} - -unsigned int getfontx2header(FILE *fp, fontx_h *header) -{ - fread(header->id, ID_LEN, 1, fp); - if (strncmp(header->id, "FONTX2", ID_LEN) != 0) - { - return 1; - } - fread(header->name, NAME_LEN, 1, fp); - header->width = (uint8_t)getc(fp); - header->height = (uint8_t)getc(fp); - header->type = (uint8_t)getc(fp); - return 0; -} - -void readfontxtbl(fontxTbl *table, unsigned int size, FILE *fp) -{ - while (size > 0) - { - table->start = chrtosht(fp); - table->end = chrtosht(fp); - ++table; - --size; - } -} - -static void LoadFontxFile(wchar_t *fname) -{ - fontx_h head; - fontxTbl *table; - unsigned int code; - uint8_t size; - unsigned int i; - - if (!fname) return; - if(*fname=='\0') return; - FILE * mfile=romfopen(fname,L"rb"); - if (!mfile) - { - pclog("MSG: Can't open FONTX2 file: %s\n",fname); - return; - } - if (getfontx2header(mfile, &head) != 0) - { - fclose(mfile); - pclog("MSG: FONTX2 header is incorrect\n"); - return; - } - /* switch whether the font is DBCS or not */ - if (head.type == DBCS) - { - if (head.width == 16 && head.height == 16) - { - size = getc(mfile); - table = (fontxTbl *)calloc(size, sizeof(fontxTbl)); - readfontxtbl(table, size, mfile); - for (i = 0; i < size; i++) - { - for (code = table[i].start; code <= table[i].end; code++) - { - fread(&jfont_dbcs_16[(code * 32)], sizeof(uint8_t), 32, mfile); - } - } - } - else - { - fclose(mfile); - pclog("MSG: FONTX2 DBCS font size is not correct\n"); - return; - } - } - else - { - if (head.width == 8 && head.height == 19) - { - fread(jfont_sbcs_19, sizeof(uint8_t), SBCS19_LEN, mfile); - } - else - { - fclose(mfile); - pclog("MSG: FONTX2 SBCS font size is not correct\n"); - return; - } - } - fclose(mfile); -} - -void *jega_standalone_init(const device_t *info) -{ - ega_t *ega = (ega_t *)ega_standalone_init(info); - - LoadFontxFile(L"roms/video/ega/JPNHN19X.FNT"); - LoadFontxFile(L"roms/video/ega/JPNZN16X.FNT"); - - ega->is_jega = 1; - - return ega; -} -#endif - - -static int ega_standalone_available(void) -{ - return rom_present(BIOS_IBM_PATH); -} - - -static int cpqega_standalone_available(void) -{ - return rom_present(BIOS_CPQ_PATH); -} - - -static int sega_standalone_available(void) -{ - return rom_present(BIOS_SEGA_PATH); -} - - -static void ega_close(void *p) -{ - ega_t *ega = (ega_t *)p; - - free(ega->vram); - free(ega); -} - - -static void ega_speed_changed(void *p) -{ - ega_t *ega = (ega_t *)p; - - ega_recalctimings(ega); -} - - -static const device_config_t ega_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 256, - { - { - "64 kB", 64 - }, - { - "128 kB", 128 - }, - { - "256 kB", 256 - }, - { - "" - } - } - }, - { - .name = "monitor_type", - .description = "Monitor type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "EGA Colour, 40x25", - .value = 6 - }, - { - .description = "EGA Colour, 80x25", - .value = 7 - }, - { - .description = "EGA Colour, ECD", - .value = 9 - }, - { - .description = "EGA Monochrome (white)", - .value = 10 | (DISPLAY_WHITE << 4) - }, - { - .description = "EGA Monochrome (green)", - .value = 10 | (DISPLAY_GREEN << 4) - }, - { - .description = "EGA Monochrome (amber)", - .value = 10 | (DISPLAY_AMBER << 4) - }, - { - .description = "" - } - }, - .default_int = 9 - }, - { - .type = -1 - } -}; - - -const device_t ega_device = -{ - "EGA", - DEVICE_ISA, - EGA_IBM, - ega_standalone_init, ega_close, NULL, - ega_standalone_available, - ega_speed_changed, - NULL, - ega_config -}; - -const device_t cpqega_device = -{ - "Compaq EGA", - DEVICE_ISA, - EGA_COMPAQ, - ega_standalone_init, ega_close, NULL, - cpqega_standalone_available, - ega_speed_changed, - NULL, - ega_config -}; - -const device_t sega_device = -{ - "SuperEGA", - DEVICE_ISA, - EGA_SUPEREGA, - ega_standalone_init, ega_close, NULL, - sega_standalone_available, - ega_speed_changed, - NULL, - ega_config -}; - -#ifdef JEGA -const device_t jega_device = -{ - "AX JEGA", - DEVICE_ISA, - EGA_SUPEREGA, - ega_standalone_init, ega_close, NULL, - sega_standalone_available, - ega_speed_changed, - NULL, - ega_config -}; -#endif diff --git a/backup code/video - Cópia/vid_ega.h b/backup code/video - Cópia/vid_ega.h deleted file mode 100644 index e5590d052..000000000 --- a/backup code/video - Cópia/vid_ega.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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 EGA, Chips & Technologies SuperEGA, and - * AX JEGA graphics cards. - * - * Version: @(#)vid_ega.h 1.0.7 2018/03/18 - * - * Authors: Sarah Walker, - * Miran Grca, - * akm, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 akm. - */ -#ifndef VIDEO_EGA_H -# define VIDEO_EGA_H - - -#ifdef JEGA -# define SBCS 0 -# define DBCS 1 -# define ID_LEN 6 -# define NAME_LEN 8 -# define SBCS19_LEN 256 * 19 -# define DBCS16_LEN 65536 * 32 -#endif - - -#if defined(EMU_MEM_H) && defined(EMU_ROM_H) -typedef struct ega_t { - mem_mapping_t mapping; - - rom_t bios_rom; - - uint8_t crtcreg; - uint8_t crtc[32]; - uint8_t gdcreg[16]; - int gdcaddr; - uint8_t attrregs[32]; - int attraddr, attrff; - int attr_palette_enable; - uint8_t seqregs[64]; - int seqaddr; - - uint8_t miscout; - int vidclock; - - uint8_t la, lb, lc, ld; - - uint8_t stat; - - int fast; - uint8_t colourcompare, colournocare; - int readmode, writemode, readplane; - int chain4, chain2_read, chain2_write; - int oddeven_page, oddeven_chain; - int extvram; - uint8_t writemask; - uint32_t charseta, charsetb; - - uint8_t egapal[16]; - uint32_t *pallook; - - int vtotal, dispend, vsyncstart, split, vblankstart; - int hdisp, htotal, hdisp_time, rowoffset; - int lowres, interlace; - int linedbl, rowcount; - double clock; - uint32_t ma_latch; - - int vres; - - int64_t dispontime, dispofftime; - int64_t vidtime; - - uint8_t scrblank; - - int dispon; - int hdisp_on; - - uint32_t ma, maback, ca; - int vc; - int sc; - int linepos, vslines, linecountff, oddeven; - int con, cursoron, blink; - int scrollcache; - - int firstline, lastline; - int firstline_draw, lastline_draw; - int displine; - - uint8_t *vram; - int vrammask; - - uint32_t vram_limit; - - int video_res_x, video_res_y, video_bpp; - -#ifdef JEGA - uint8_t RMOD1, RMOD2, RDAGS, RDFFB, RDFSB, RDFAP, RPESL, RPULP, RPSSC, RPSSU, RPSSL; - uint8_t RPPAJ; - uint8_t RCMOD, RCCLH, RCCLL, RCCSL, RCCEL, RCSKW, ROMSL, RSTAT; - int is_jega, font_index; - int chr_left, chr_wide; -#endif -} ega_t; -#endif - - -#ifdef EMU_DEVICE_H -extern const device_t ega_device; -extern const device_t cpqega_device; -extern const device_t sega_device; -#endif -#ifdef JEGA -extern uint8_t jfont_sbcs_19[SBCS19_LEN]; /* 256 * 19( * 8) */ -extern uint8_t jfont_dbcs_16[DBCS16_LEN]; /* 65536 * 16 * 2 (* 8) */ -#endif - -extern int update_overscan; - -#define DISPLAY_RGB 0 -#define DISPLAY_COMPOSITE 1 -#define DISPLAY_RGB_NO_BROWN 2 -#define DISPLAY_GREEN 3 -#define DISPLAY_AMBER 4 -#define DISPLAY_WHITE 5 - - -#if defined(EMU_MEM_H) && defined(EMU_ROM_H) -extern void ega_init(ega_t *ega, int monitor_type, int is_mono); -extern void ega_recalctimings(struct ega_t *ega); -#endif - -extern void ega_out(uint16_t addr, uint8_t val, void *p); -extern uint8_t ega_in(uint16_t addr, void *p); -extern void ega_poll(void *p); -extern void ega_write(uint32_t addr, uint8_t val, void *p); -extern uint8_t ega_read(uint32_t addr, void *p); - - -#endif /*VIDEO_EGA_H*/ diff --git a/backup code/video - Cópia/vid_ega_render.c b/backup code/video - Cópia/vid_ega_render.c deleted file mode 100644 index 06b697cc8..000000000 --- a/backup code/video - Cópia/vid_ega_render.c +++ /dev/null @@ -1,550 +0,0 @@ -/* - * 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. - * - * EGA renderers. - * - * Version: @(#)vid_ega_render.c 1.0.5 2018/01/24 - * - * Author: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../rom.h" -#include "video.h" -#include "vid_ega.h" -#include "vid_ega_render.h" - - -int ega_display_line(ega_t *ega) -{ - int y_add = (enable_overscan) ? (overscan_y >> 1) : 0; - unsigned int dl = ega->displine; - if (ega->crtc[9] & 0x1f) - { - dl -= (ega->crtc[8] & 0x1f); - } - dl += y_add; - dl &= 0x7ff; - return dl; -} - -void ega_render_blank(ega_t *ega) -{ - int x_add = (enable_overscan) ? 8 : 0; - int dl = ega_display_line(ega); - int x, xx; - - for (x = 0; x < ega->hdisp; x++) - { - switch (ega->seqregs[1] & 9) - { - case 0: - for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[dl])[(x * 9) + xx + 32 + x_add] = 0; - break; - case 1: - for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[dl])[(x * 8) + xx + 32 + x_add] = 0; - break; - case 8: - for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[dl])[(x * 18) + xx + 32 + x_add] = 0; - break; - case 9: - for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[dl])[(x * 16) + xx + 32 + x_add] = 0; - break; - } - } -} - -void ega_render_text_standard(ega_t *ega, int drawcursor) -{ - int x, xx; - int x_add = (enable_overscan) ? 8 : 0; - int dl = ega_display_line(ega); - - for (x = 0; x < ega->hdisp; x++) - { - int drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); - uint8_t chr = ega->vram[(ega->ma << 1) & ega->vrammask]; - uint8_t attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; - uint8_t dat; - uint32_t fg, bg; - uint32_t charaddr; - - if (attr & 8) - charaddr = ega->charsetb + (chr * 128); - else - charaddr = ega->charseta + (chr * 128); - - if (drawcursor) - { - bg = ega->pallook[ega->egapal[attr & 15]]; - fg = ega->pallook[ega->egapal[attr >> 4]]; - } - else - { - fg = ega->pallook[ega->egapal[attr & 15]]; - bg = ega->pallook[ega->egapal[attr >> 4]]; - if (attr & 0x80 && ega->attrregs[0x10] & 8) - { - bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; - if (ega->blink & 16) - fg = bg; - } - } - - dat = ega->vram[charaddr + (ega->sc << 2)]; - if (ega->seqregs[1] & 8) - { - if (ega->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[((x << 4) + 32 + (xx << 1) + x_add) & 2047] = - ((uint32_t *)buffer32->line[dl])[((x << 4) + 33 + (xx << 1) + x_add) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[((x * 18) + 32 + (xx << 1) + x_add) & 2047] = - ((uint32_t *)buffer32->line[dl])[((x * 18) + 33 + (xx << 1) + x_add) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[dl])[((x * 18) + 32 + 16 + x_add) & 2047] = - ((uint32_t *)buffer32->line[dl])[((x * 18) + 32 + 17 + x_add) & 2047] = bg; - else - ((uint32_t *)buffer32->line[dl])[((x * 18) + 32 + 16 + x_add) & 2047] = - ((uint32_t *)buffer32->line[dl])[((x * 18) + 32 + 17 + x_add) & 2047] = (dat & 1) ? fg : bg; - } - } - else - { - if (ega->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[((x << 3) + 32 + xx + x_add) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[((x * 9) + 32 + xx + x_add) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[dl])[((x * 9) + 32 + 8 + x_add) & 2047] = bg; - else - ((uint32_t *)buffer32->line[dl])[((x * 9) + 32 + 8 + x_add) & 2047] = (dat & 1) ? fg : bg; - } - } - ega->ma += 4; - ega->ma &= ega->vrammask; - } -} - -#ifdef JEGA -static __inline int is_kanji1(uint8_t chr) -{ - return (chr >= 0x81 && chr <= 0x9f) || (chr >= 0xe0 && chr <= 0xfc); -} - -static __inline int is_kanji2(uint8_t chr) -{ - return (chr >= 0x40 && chr <= 0x7e) || (chr >= 0x80 && chr <= 0xfc); -} - -void ega_jega_render_blit_text(ega_t *ega, int x, int dl, int start, int width, uint16_t dat, int cw, uint32_t fg, uint32_t bg) -{ - int x_add = (enable_overscan) ? 8 : 0; - - int xx = 0; - int xxx = 0; - - if (ega->seqregs[1] & 8) - { - for (xx = start; xx < (start + width); xx++) - for (xxx = 0; xxx < cw; xxx++) - ((uint32_t *)buffer32->line[dl])[(((x * width) + 32 + (xxx << 1) + ((xx << 1) * cw)) & 2047) + x_add] = - ((uint32_t *)buffer32->line[dl])[(((x * width) + 33 + (xxx << 1) + ((xx << 1) * cw)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = start; xx < (start + width); xx++) - ((uint32_t *)buffer32->line[dl])[(((x * width) + 32 + xxx + (xx * cw)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - } -} - -void ega_render_text_jega(ega_t *ega, int drawcursor) -{ - int dl = ega_display_line(ega); - uint8_t chr, attr; - uint16_t dat = 0, dat2; - int x; - uint32_t fg = 0, bg = 0; - - /* Temporary for DBCS. */ - unsigned int chr_left = 0; - unsigned int bsattr = 0; - int chr_wide = 0; - uint32_t bg_ex = 0; - uint32_t fg_ex = 0; - - int blocks = ega->hdisp; - int fline; - - unsigned int pad_y, exattr; - - if (fullchange) - { - for (x = 0; x < ega->hdisp; x++) - { - drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); - chr = ega->vram[(ega->ma << 1) & ega->vrammask]; - attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; - - if (chr_wide == 0) - { - if (ega->RMOD2 & 0x80) - { - fg_ex = ega->pallook[ega->egapal[attr & 15]]; - - if (attr & 0x80 && ega->attrregs[0x10] & 8) - { - bg_ex = ega->pallook[ega->egapal[(attr >> 4) & 7]]; - } - else - { - bg_ex = ega->pallook[ega->egapal[attr >> 4]]; - } - } - else - { - if (attr & 0x40) - { - /* Reversed in JEGA mode */ - bg_ex = ega->pallook[ega->egapal[attr & 15]]; - fg_ex = ega->pallook[0]; - } - else - { - /* Reversed in JEGA mode */ - fg_ex = ega->pallook[ega->egapal[attr & 15]]; - bg_ex = ega->pallook[0]; - } - } - - if (drawcursor) - { - bg = fg_ex; - fg = bg_ex; - } - else - { - fg = fg_ex; - bg = bg_ex; - } - - if (attr & 0x80 && ega->attrregs[0x10] & 8) - { - if (ega->blink & 16) - fg = bg; - } - - /* Stay drawing if the char code is DBCS and not at last column. */ - if (is_kanji1(dat) && (blocks > 1)) - { - /* Set the present char/attr code to the next loop. */ - chr_left = chr; - chr_wide = 1; - } - else - { - /* The char code is ANK (8 dots width). */ - dat = jfont_sbcs_19[chr*19+(ega->sc)]; /* w8xh19 font */ - ega_jega_render_blit_text(ega, x, dl, 0, 8, dat, 1, fg, bg); - if (bsattr & 0x20) - { - /* Vertical line. */ - dat = 0x18; - ega_jega_render_blit_text(ega, x, fline, 0, 8, dat, 1, fg, bg); - } - if (ega->sc == 18 && bsattr & 0x10) - { - /* Underline. */ - dat = 0xff; - ega_jega_render_blit_text(ega, x, fline, 0, 8, dat, 1, fg, bg); - } - chr_wide = 0; - blocks--; - } - } - else - { - /* The char code may be in DBCS. */ - pad_y = ega->RPSSC; - exattr = 0; - - /* Note: The second column should be applied its basic attribute. */ - if (ega->RMOD2 & 0x40) - { - /* If JEGA Extended Attribute is enabled. */ - exattr = attr; - if ((exattr & 0x30) == 0x30) pad_y = ega->RPSSL; /* Set top padding of lower 2x character. */ - else if (exattr & 0x30) pad_y = ega->RPSSU; /* Set top padding of upper 2x character. */ - } - - if (ega->sc >= pad_y && ega->sc < 16 + pad_y) - { - /* Check the char code is in Wide charset of Shift-JIS. */ - if (is_kanji2(chr)) - { - fline = ega->sc - pad_y; - chr_left <<= 8; - /* Fix vertical position. */ - chr |= chr_left; - /* Horizontal wide font (Extended Attribute). */ - if (exattr & 0x20) - { - if (exattr & 0x10) fline = (fline >> 1) + 8; - else fline = fline >> 1; - } - /* Vertical wide font (Extended Attribute). */ - if (exattr & 0x40) - { - dat = jfont_dbcs_16[chr * 32 + fline * 2]; - if (!(exattr & 0x08)) - dat = jfont_dbcs_16[chr * 32 + fline * 2 + 1]; - /* Draw 8 dots. */ - ega_jega_render_blit_text(ega, x, dl, 0, 8, dat, 2, fg, bg); - } - else - { - /* Get the font pattern. */ - dat = jfont_dbcs_16[chr * 32 + fline * 2]; - dat <<= 8; - dat |= jfont_dbcs_16[chr * 32 + fline * 2 + 1]; - /* Bold (Extended Attribute). */ - if (exattr &= 0x80) - { - dat2 = dat; - dat2 >>= 1; - dat |= dat2; - /* Original JEGA colours the last row with the next column's attribute. */ - } - /* Draw 16 dots */ - ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg); - } - } - else - { - /* Ignore wide char mode, put blank. */ - dat = 0; - ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg); - } - } - else if (ega->sc == (17 + pad_y) && (bsattr & 0x10)) - { - /* Underline. */ - dat = 0xffff; - ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg); - } - else - { - /* Draw blank */ - dat = 0; - ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg); - } - - if (bsattr & 0x20) - { - /* Vertical line draw at last. */ - dat = 0x0180; - ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg); - } - - chr_wide = 0; - blocks -= 2; /* Move by 2 columns. */ - } - - ega->ma += 4; - ega->ma &= ega->vrammask; - } - } -} -#endif - -void ega_render_2bpp(ega_t *ega) -{ - int x; - int dl = ega_display_line(ega); - int offset = ((8 - ega->scrollcache) << 1) + 16; - - for (x = 0; x <= ega->hdisp; x++) - { - uint8_t edat[2]; - uint32_t addr = ega->ma; - - if (!(ega->crtc[0x17] & 0x40)) - { - addr = (addr << 1) & ega->vrammask; - addr &= ~7; - if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) - addr |= 4; - if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) - addr |= 4; - } - if (!(ega->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); - if (!(ega->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); - - edat[0] = ega->vram[addr]; - edat[1] = ega->vram[addr | 0x1]; - if (ega->seqregs[1] & 4) - ega->ma += 2; - else - ega->ma += 4; - - ega->ma &= ega->vrammask; - - ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 15 + offset] = ega->pallook[ega->egapal[edat[1] & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 13 + offset] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 10 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 11 + offset] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 8 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 9 + offset] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 7 + offset] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 5 + offset] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 3 + offset] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 1 + offset] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; - } -} - -void ega_render_4bpp_lowres(ega_t *ega) -{ - int x_add = (enable_overscan) ? 8 : 0; - int dl = ega_display_line(ega); - int x; - int offset = ((8 - ega->scrollcache) << 1) + 16; - - for (x = 0; x <= ega->hdisp; x++) - { - uint8_t edat[4]; - uint8_t dat; - uint32_t addr = ega->ma; - int oddeven = 0; - - if (!(ega->crtc[0x17] & 0x40)) - { - addr = (addr << 1) & ega->vrammask; - if (ega->seqregs[1] & 4) - oddeven = (addr & 4) ? 1 : 0; - addr &= ~7; - if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) - addr |= 4; - if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) - addr |= 4; - } - if (!(ega->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); - if (!(ega->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); - - if (ega->seqregs[1] & 4) - { - edat[0] = ega->vram[addr | oddeven]; - edat[2] = ega->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - ega->ma += 2; - } - else - { - edat[0] = ega->vram[addr]; - edat[1] = ega->vram[addr | 0x1]; - edat[2] = ega->vram[addr | 0x2]; - edat[3] = ega->vram[addr | 0x3]; - ega->ma += 4; - } - ega->ma &= ega->vrammask; - - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - } -} - -void ega_render_4bpp_highres(ega_t *ega) -{ - int x_add = (enable_overscan) ? 8 : 0; - int dl = ega_display_line(ega); - int x; - int offset = (8 - ega->scrollcache) + 24; - - for (x = 0; x <= ega->hdisp; x++) - { - uint8_t edat[4]; - uint8_t dat; - uint32_t addr = ega->ma; - int oddeven = 0; - - if (!(ega->crtc[0x17] & 0x40)) - { - addr = (addr << 1) & ega->vrammask; - if (ega->seqregs[1] & 4) - oddeven = (addr & 4) ? 1 : 0; - addr &= ~7; - if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) - addr |= 4; - if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) - addr |= 4; - } - if (!(ega->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); - if (!(ega->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); - - if (ega->seqregs[1] & 4) - { - edat[0] = ega->vram[addr | oddeven]; - edat[2] = ega->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - ega->ma += 2; - } - else - { - edat[0] = ega->vram[addr]; - edat[1] = ega->vram[addr | 0x1]; - edat[2] = ega->vram[addr | 0x2]; - edat[3] = ega->vram[addr | 0x3]; - ega->ma += 4; - } - ega->ma &= ega->vrammask; - - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 3) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 3) + 6 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 3) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 3) + 4 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 3) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 3) + 2 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 3) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 3) + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - } -} diff --git a/backup code/video - Cópia/vid_ega_render.h b/backup code/video - Cópia/vid_ega_render.h deleted file mode 100644 index 57cb8313b..000000000 --- a/backup code/video - Cópia/vid_ega_render.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - * - * EGA renderers. - * - * Version: @(#)vid_ega_render.h 1.0.2 2018/01/24 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -extern int firstline_draw, lastline_draw; -extern int displine; -extern int sc; - -extern uint32_t ma, ca; -extern int con, cursoron, cgablink; - -extern int scrollcache; - -extern uint8_t edatlookup[4][4]; - -void ega_render_blank(ega_t *ega); -void ega_render_text_standard(ega_t *ega, int drawcursor); -#ifdef JEGA -void ega_render_text_jega(ega_t *ega, int drawcursor); -#endif - -void ega_render_2bpp(ega_t *ega); - -void ega_render_4bpp_lowres(ega_t *ega); -void ega_render_4bpp_highres(ega_t *ega); diff --git a/backup code/video - Cópia/vid_et4000.c b/backup code/video - Cópia/vid_et4000.c deleted file mode 100644 index 5db6c55d9..000000000 --- a/backup code/video - Cópia/vid_et4000.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * 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 Tseng Labs ET4000. - * - * Version: @(#)vid_et4000.c 1.0.6 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_sc1502x_ramdac.h" -#include "vid_et4000.h" - - -#define BIOS_ROM_PATH L"roms/video/et4000/et4000.bin" - - -typedef struct et4000_t -{ - svga_t svga; - sc1502x_ramdac_t ramdac; - - rom_t bios_rom; - - uint8_t banking; -} et4000_t; - -static uint8_t crtc_mask[0x40] = -{ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -void et4000_out(uint16_t addr, uint8_t val, void *p) -{ - et4000_t *et4000 = (et4000_t *)p; - svga_t *svga = &et4000->svga; - - uint8_t old; - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - sc1502x_ramdac_out(addr, val, &et4000->ramdac, svga); - return; - - case 0x3CD: /*Banking*/ - svga->write_bank = (val & 0xf) * 0x10000; - svga->read_bank = ((val >> 4) & 0xf) * 0x10000; - et4000->banking = val; - return; - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - val &= crtc_mask[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) - { - if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); -} - -uint8_t et4000_in(uint16_t addr, void *p) -{ - et4000_t *et4000 = (et4000_t *)p; - svga_t *svga = &et4000->svga; - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3C5: - if ((svga->seqaddr & 0xf) == 7) return svga->seqregs[svga->seqaddr & 0xf] | 4; - break; - - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - return sc1502x_ramdac_in(addr, &et4000->ramdac, svga); - - case 0x3CD: /*Banking*/ - return et4000->banking; - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); -} - -void et4000_recalctimings(svga_t *svga) -{ - svga->ma_latch |= (svga->crtc[0x33]&3)<<16; - if (svga->crtc[0x35] & 1) svga->vblankstart += 0x400; - if (svga->crtc[0x35] & 2) svga->vtotal += 0x400; - if (svga->crtc[0x35] & 4) svga->dispend += 0x400; - if (svga->crtc[0x35] & 8) svga->vsyncstart += 0x400; - if (svga->crtc[0x35] & 0x10) svga->split += 0x400; - if (!svga->rowoffset) svga->rowoffset = 0x100; - if (svga->crtc[0x3f] & 1) svga->htotal += 256; - if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; - - switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) - { - case 0: case 1: break; - case 3: svga->clock = cpuclock / 40000000.0; break; - case 5: svga->clock = cpuclock / 65000000.0; break; - default: svga->clock = cpuclock / 36000000.0; break; - } - - switch (svga->bpp) - { - case 15: case 16: - svga->hdisp /= 2; - break; - case 24: - svga->hdisp /= 3; - break; - } -} - -void *et4000_init(const device_t *info) -{ - et4000_t *et4000 = malloc(sizeof(et4000_t)); - memset(et4000, 0, sizeof(et4000_t)); - - rom_init(&et4000->bios_rom, BIOS_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); - - svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/ - et4000_recalctimings, - et4000_in, et4000_out, - NULL, - NULL); - - return et4000; -} - -static int et4000_available(void) -{ - return rom_present(BIOS_ROM_PATH); -} - -void et4000_close(void *p) -{ - et4000_t *et4000 = (et4000_t *)p; - - svga_close(&et4000->svga); - - free(et4000); -} - -void et4000_speed_changed(void *p) -{ - et4000_t *et4000 = (et4000_t *)p; - - svga_recalctimings(&et4000->svga); -} - -void et4000_force_redraw(void *p) -{ - et4000_t *et4000 = (et4000_t *)p; - - et4000->svga.fullchange = changeframecount; -} - -const device_t et4000_device = -{ - "Tseng Labs ET4000AX", - DEVICE_ISA, 0, - et4000_init, et4000_close, NULL, - et4000_available, - et4000_speed_changed, - et4000_force_redraw, - NULL -}; diff --git a/backup code/video - Cópia/vid_et4000.h b/backup code/video - Cópia/vid_et4000.h deleted file mode 100644 index 803f84729..000000000 --- a/backup code/video - Cópia/vid_et4000.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t et4000_device; diff --git a/backup code/video - Cópia/vid_et4000w32.c b/backup code/video - Cópia/vid_et4000w32.c deleted file mode 100644 index 0d9b4ff06..000000000 --- a/backup code/video - Cópia/vid_et4000w32.c +++ /dev/null @@ -1,1392 +0,0 @@ -/* - * 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. - * - * ET4000/W32p emulation (Diamond Stealth 32) - * - * Known bugs: Accelerator doesn't work in planar modes - * - * Version: @(#)vid_et4000w32.c 1.0.10 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "../plat.h" -#include "video.h" -#include "vid_svga.h" -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) -#include "vid_icd2061.h" -#endif -#include "vid_stg_ramdac.h" - - -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) -#define BIOS_ROM_PATH_DIAMOND L"roms/video/et4000w32/et4000w32.bin" -#endif -#define BIOS_ROM_PATH_CARDEX L"roms/video/et4000w32/cardex.vbi" - - -#define FIFO_SIZE 65536 -#define FIFO_MASK (FIFO_SIZE - 1) -#define FIFO_ENTRY_SIZE (1 << 31) - -#define FIFO_ENTRIES (et4000->fifo_write_idx - et4000->fifo_read_idx) -#define FIFO_FULL ((et4000->fifo_write_idx - et4000->fifo_read_idx) >= (FIFO_SIZE-1)) -#define FIFO_EMPTY (et4000->fifo_read_idx == et4000->fifo_write_idx) - -#define FIFO_TYPE 0xff000000 -#define FIFO_ADDR 0x00ffffff - -enum -{ - ET4000W32_CARDEX = 0, -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) - ET4000W32_DIAMOND -#endif -}; - -enum -{ - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_MMU = (0x02 << 24) -}; - -typedef struct -{ - uint32_t addr_type; - uint32_t val; -} fifo_entry_t; - -typedef struct et4000w32p_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t mmu_mapping; - - rom_t bios_rom; - - svga_t svga; - stg_ramdac_t ramdac; -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) - icd2061_t icd2061; -#endif - - int index; - int pci; - uint8_t regs[256]; - uint32_t linearbase, linearbase_old; - - uint8_t banking, banking2; - - uint8_t pci_regs[256]; - - int interleaved; - - /*Accelerator*/ - struct - { - struct - { - uint32_t pattern_addr,source_addr,dest_addr,mix_addr; - uint16_t pattern_off,source_off,dest_off,mix_off; - uint8_t pixel_depth,xy_dir; - uint8_t pattern_wrap,source_wrap; - uint16_t count_x,count_y; - uint8_t ctrl_routing,ctrl_reload; - uint8_t rop_fg,rop_bg; - uint16_t pos_x,pos_y; - uint16_t error; - uint16_t dmin,dmaj; - } queued,internal; - uint32_t pattern_addr,source_addr,dest_addr,mix_addr; - uint32_t pattern_back,source_back,dest_back,mix_back; - int pattern_x,source_x; - int pattern_x_back,source_x_back; - int pattern_y,source_y; - uint8_t status; - uint64_t cpu_dat; - int cpu_dat_pos; - int pix_pos; - } acl; - - struct - { - uint32_t base[3]; - uint8_t ctrl; - } mmu; - - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; - - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; - - int blitter_busy; - uint64_t blitter_time; - uint64_t status_time; - int type; -} et4000w32p_t; - -void et4000w32p_recalcmapping(et4000w32p_t *et4000); - -uint8_t et4000w32p_mmu_read(uint32_t addr, void *p); -void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p); - -void et4000w32_blit_start(et4000w32p_t *et4000); -void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000); - - -#ifdef ENABLE_ET4000W32_LOG -int et4000w32_do_log = ENABLE_ET4000W32_LOG; -#endif - - -static void -et4000w32_log(const char *format, ...) -{ -#ifdef ENABLE_ET4000W32_LOG - va_list ap; - - if (et4000w32_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -void et4000w32p_out(uint16_t addr, uint8_t val, void *p) -{ - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; - uint8_t old; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) - case 0x3c2: - if (et4000->type == ET4000W32_DIAMOND) - icd2061_write(&et4000->icd2061, (val >> 2) & 3); - break; -#endif - - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - stg_ramdac_out(addr, val, &et4000->ramdac, svga); - return; - - case 0x3CB: /*Banking extension*/ - svga->write_bank = (svga->write_bank & 0xfffff) | ((val & 1) << 20); - svga->read_bank = (svga->read_bank & 0xfffff) | ((val & 0x10) << 16); - et4000->banking2 = val; - return; - case 0x3CD: /*Banking*/ - svga->write_bank = (svga->write_bank & 0x100000) | ((val & 0xf) * 65536); - svga->read_bank = (svga->read_bank & 0x100000) | (((val >> 4) & 0xf) * 65536); - et4000->banking = val; - return; - case 0x3CF: - switch (svga->gdcaddr & 15) - { - case 6: - svga->gdcreg[svga->gdcaddr & 15] = val; - et4000w32p_recalcmapping(et4000); - return; - } - break; - case 0x3D4: - svga->crtcreg = val & 63; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - if (svga->crtcreg == 0x30) - { - if (et4000->pci) - { - et4000->linearbase &= 0xc0000000; - et4000->linearbase = (val & 0xfc) << 22; - } - else - { - et4000->linearbase = val << 22; - } - et4000w32p_recalcmapping(et4000); - } - if (svga->crtcreg == 0x32 || svga->crtcreg == 0x36) - et4000w32p_recalcmapping(et4000); - break; - - case 0x210A: case 0x211A: case 0x212A: case 0x213A: - case 0x214A: case 0x215A: case 0x216A: case 0x217A: - et4000->index=val; - return; - case 0x210B: case 0x211B: case 0x212B: case 0x213B: - case 0x214B: case 0x215B: case 0x216B: case 0x217B: - et4000->regs[et4000->index] = val; - svga->hwcursor.x = et4000->regs[0xE0] | ((et4000->regs[0xE1] & 7) << 8); - svga->hwcursor.y = et4000->regs[0xE4] | ((et4000->regs[0xE5] & 7) << 8); - svga->hwcursor.addr = (et4000->regs[0xE8] | (et4000->regs[0xE9] << 8) | ((et4000->regs[0xEA] & 7) << 16)) << 2; - svga->hwcursor.addr += (et4000->regs[0xE6] & 63) * 16; - svga->hwcursor.ena = et4000->regs[0xF7] & 0x80; - svga->hwcursor.xoff = et4000->regs[0xE2] & 63; - svga->hwcursor.yoff = et4000->regs[0xE6] & 63; - return; - - } - svga_out(addr, val, svga); -} - -uint8_t et4000w32p_in(uint16_t addr, void *p) -{ - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3c5: - if ((svga->seqaddr & 0xf) == 7) - return svga->seqregs[svga->seqaddr & 0xf] | 4; - break; - - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - return stg_ramdac_in(addr, &et4000->ramdac, svga); - - case 0x3CB: - return et4000->banking2; - case 0x3CD: - return et4000->banking; - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - return svga->crtc[svga->crtcreg]; - - case 0x210A: case 0x211A: case 0x212A: case 0x213A: - case 0x214A: case 0x215A: case 0x216A: case 0x217A: - return et4000->index; - case 0x210B: case 0x211B: case 0x212B: case 0x213B: - case 0x214B: case 0x215B: case 0x216B: case 0x217B: - if (et4000->index==0xec) - return (et4000->regs[0xec] & 0xf) | 0x60; /*ET4000/W32p rev D*/ - if (et4000->index == 0xee) /*Preliminary implementation*/ - { - if (svga->bpp == 8) - return 3; - else if (svga->bpp == 16) - return 4; - else - break; - } - if (et4000->index == 0xef) - { - if (et4000->pci) return et4000->regs[0xef] | 0xe0; /*PCI*/ - else return et4000->regs[0xef] | 0x60; /*VESA local bus*/ - } - return et4000->regs[et4000->index]; - } - return svga_in(addr, svga); -} - -void et4000w32p_recalctimings(svga_t *svga) -{ - et4000w32p_t *et4000 = (et4000w32p_t *)svga->p; - svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; - if (svga->crtc[0x35] & 0x01) svga->vblankstart += 0x400; - if (svga->crtc[0x35] & 0x02) svga->vtotal += 0x400; - if (svga->crtc[0x35] & 0x04) svga->dispend += 0x400; - if (svga->crtc[0x35] & 0x08) svga->vsyncstart += 0x400; - if (svga->crtc[0x35] & 0x10) svga->split += 0x400; - if (svga->crtc[0x3F] & 0x80) svga->rowoffset += 0x100; - if (svga->crtc[0x3F] & 0x01) svga->htotal += 256; - if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; - -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) - if (et4000->type == ET4000W32_DIAMOND) - { - switch ((svga->miscout >> 2) & 3) - { - case 0: case 1: break; - case 2: case 3: svga->clock = cpuclock / icd2061_getfreq(&et4000->icd2061, 2); break; - } - } - else - { -#endif - svga->clock = cpuclock / stg_getclock((svga->miscout >> 2) & 3, &et4000->ramdac); -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) - } -#endif - - switch (svga->bpp) - { - case 15: case 16: - svga->hdisp >>= 1; - break; - case 24: - svga->hdisp /= 3; - break; - } -} - -void et4000w32p_recalcmapping(et4000w32p_t *et4000) -{ - svga_t *svga = &et4000->svga; - - if (!(et4000->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) - { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&et4000->linear_mapping); - mem_mapping_disable(&et4000->mmu_mapping); - return; - } - - if (svga->crtc[0x36] & 0x10) /*Linear frame buffer*/ - { - mem_mapping_set_addr(&et4000->linear_mapping, et4000->linearbase, 0x200000); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&et4000->mmu_mapping); - } - else - { - int map = (svga->gdcreg[6] & 0xc) >> 2; - if (svga->crtc[0x36] & 0x20) map |= 4; - if (svga->crtc[0x36] & 0x08) map |= 8; - switch (map) - { - case 0x0: case 0x4: case 0x8: case 0xC: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - mem_mapping_disable(&et4000->mmu_mapping); - svga->banked_mask = 0xffff; - break; - case 0x1: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_disable(&et4000->mmu_mapping); - svga->banked_mask = 0xffff; - break; - case 0x2: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - mem_mapping_disable(&et4000->mmu_mapping); - svga->banked_mask = 0x7fff; - break; - case 0x3: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - mem_mapping_disable(&et4000->mmu_mapping); - svga->banked_mask = 0x7fff; - break; - case 0x5: case 0x9: case 0xD: /*64k at A0000, MMU at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_set_addr(&et4000->mmu_mapping, 0xb8000, 0x08000); - svga->banked_mask = 0xffff; - break; - case 0x6: case 0xA: case 0xE: /*32k at B0000, MMU at A8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0x7: case 0xB: case 0xF: /*32k at B8000, MMU at A8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - - mem_mapping_disable(&et4000->linear_mapping); - } - et4000->linearbase_old = et4000->linearbase; - - if (!et4000->interleaved && (et4000->svga.crtc[0x32] & 0x80)) - mem_mapping_disable(&svga->mapping); -} - -#define ACL_WRST 1 -#define ACL_RDST 2 -#define ACL_XYST 4 -#define ACL_SSO 8 - -static void et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) -{ - switch (addr & 0x7fff) - { - case 0x7f80: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFFFF00) | val; break; - case 0x7f81: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFF00FF) | (val << 8); break; - case 0x7f82: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFF00FFFF) | (val << 16); break; - case 0x7f83: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00FFFFFF) | (val << 24); break; - case 0x7f84: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFFFF00) | val; break; - case 0x7f85: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFF00FF) | (val << 8); break; - case 0x7f86: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFF00FFFF) | (val << 16); break; - case 0x7f87: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00FFFFFF) | (val << 24); break; - case 0x7f88: et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0xFF00) | val; break; - case 0x7f89: et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00FF) | (val << 8); break; - case 0x7f8a: et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0xFF00) | val; break; - case 0x7f8b: et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00FF) | (val << 8); break; - case 0x7f8c: et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0xFF00) | val; break; - case 0x7f8d: et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00FF) | (val << 8); break; - case 0x7f8e: et4000->acl.queued.pixel_depth = val; break; - case 0x7f8f: et4000->acl.queued.xy_dir = val; break; - case 0x7f90: et4000->acl.queued.pattern_wrap = val; break; - case 0x7f92: et4000->acl.queued.source_wrap = val; break; - case 0x7f98: et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0xFF00) | val; break; - case 0x7f99: et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00FF) | (val << 8); break; - case 0x7f9a: et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0xFF00) | val; break; - case 0x7f9b: et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00FF) | (val << 8); break; - case 0x7f9c: et4000->acl.queued.ctrl_routing = val; break; - case 0x7f9d: et4000->acl.queued.ctrl_reload = val; break; - case 0x7f9e: et4000->acl.queued.rop_bg = val; break; - case 0x7f9f: et4000->acl.queued.rop_fg = val; break; - case 0x7fa0: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFFFF00) | val; break; - case 0x7fa1: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFF00FF) | (val << 8); break; - case 0x7fa2: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFF00FFFF) | (val << 16); break; - case 0x7fa3: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00FFFFFF) | (val << 24); - et4000->acl.internal = et4000->acl.queued; - et4000w32_blit_start(et4000); - if (!(et4000->acl.queued.ctrl_routing & 0x43)) - { - et4000w32_blit(0xFFFFFF, ~0, 0, 0, et4000); - } - if ((et4000->acl.queued.ctrl_routing & 0x40) && !(et4000->acl.internal.ctrl_routing & 3)) - et4000w32_blit(4, ~0, 0, 0, et4000); - break; - case 0x7fa4: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFFFF00) | val; break; - case 0x7fa5: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFF00FF) | (val << 8); break; - case 0x7fa6: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFF00FFFF) | (val << 16); break; - case 0x7fa7: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0x00FFFFFF) | (val << 24); break; - case 0x7fa8: et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0xFF00) | val; break; - case 0x7fa9: et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0x00FF) | (val << 8); break; - case 0x7faa: et4000->acl.queued.error = (et4000->acl.queued.error & 0xFF00) | val; break; - case 0x7fab: et4000->acl.queued.error = (et4000->acl.queued.error & 0x00FF) | (val << 8); break; - case 0x7fac: et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0xFF00) | val; break; - case 0x7fad: et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0x00FF) | (val << 8); break; - case 0x7fae: et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0xFF00) | val; break; - case 0x7faf: et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0x00FF) | (val << 8); break; - } -} - -static void et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val) -{ - if (!(et4000->acl.status & ACL_XYST)) return; - if (et4000->acl.internal.ctrl_routing & 3) - { - if ((et4000->acl.internal.ctrl_routing & 3) == 2) - { - if (et4000->acl.mix_addr & 7) - et4000w32_blit(8 - (et4000->acl.mix_addr & 7), val >> (et4000->acl.mix_addr & 7), 0, 1, et4000); - else - et4000w32_blit(8, val, 0, 1, et4000); - } - else if ((et4000->acl.internal.ctrl_routing & 3) == 1) - et4000w32_blit(1, ~0, val, 2, et4000); - } -} - -static void fifo_thread(void *param) -{ - et4000w32p_t *et4000 = (et4000w32p_t *)param; - - uint64_t start_time = 0; - uint64_t end_time = 0; - - fifo_entry_t *fifo; - - while (1) - { - thread_set_event(et4000->fifo_not_full_event); - thread_wait_event(et4000->wake_fifo_thread, -1); - thread_reset_event(et4000->wake_fifo_thread); - et4000->blitter_busy = 1; - while (!FIFO_EMPTY) - { - start_time = plat_timer_read(); - fifo = &et4000->fifo[et4000->fifo_read_idx & FIFO_MASK]; - - switch (fifo->addr_type & FIFO_TYPE) - { - case FIFO_WRITE_BYTE: - et4000w32p_accel_write_fifo(et4000, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_MMU: - et4000w32p_accel_write_mmu(et4000, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - } - - et4000->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; - - if (FIFO_ENTRIES > 0xe000) - thread_set_event(et4000->fifo_not_full_event); - - end_time = plat_timer_read(); - et4000->blitter_time += end_time - start_time; - } - et4000->blitter_busy = 0; - } -} - -static __inline void wake_fifo_thread(et4000w32p_t *et4000) -{ - thread_set_event(et4000->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ -} - -static void et4000w32p_wait_fifo_idle(et4000w32p_t *et4000) -{ - while (!FIFO_EMPTY) - { - wake_fifo_thread(et4000); - thread_wait_event(et4000->fifo_not_full_event, 1); - } -} - -static void et4000w32p_queue(et4000w32p_t *et4000, uint32_t addr, uint32_t val, uint32_t type) -{ - fifo_entry_t *fifo = &et4000->fifo[et4000->fifo_write_idx & FIFO_MASK]; - - if (FIFO_FULL) - { - thread_reset_event(et4000->fifo_not_full_event); - if (FIFO_FULL) - { - thread_wait_event(et4000->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } - - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; - - et4000->fifo_write_idx++; - - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(et4000); -} - -void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p) -{ - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; - int bank; - switch (addr & 0x6000) - { - case 0x0000: /*MMU 0*/ - case 0x2000: /*MMU 1*/ - case 0x4000: /*MMU 2*/ - bank = (addr >> 13) & 3; - if (et4000->mmu.ctrl & (1 << bank)) - { - et4000w32p_queue(et4000, addr & 0x7fff, val, FIFO_WRITE_MMU); - } - else - { - if ((addr&0x1fff) + et4000->mmu.base[bank] < svga->vram_max) - { - svga->vram[(addr & 0x1fff) + et4000->mmu.base[bank]] = val; - svga->changedvram[((addr & 0x1fff) + et4000->mmu.base[bank]) >> 12] = changeframecount; - } - } - break; - case 0x6000: - if ((addr & 0x7fff) >= 0x7f80) - { - et4000w32p_queue(et4000, addr & 0x7fff, val, FIFO_WRITE_BYTE); - } - else switch (addr & 0x7fff) - { - case 0x7f00: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFFFF00) | val; break; - case 0x7f01: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFF00FF) | (val << 8); break; - case 0x7f02: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFF00FFFF) | (val << 16); break; - case 0x7f03: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00FFFFFF) | (val << 24); break; - case 0x7f04: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFFFF00) | val; break; - case 0x7f05: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFF00FF) | (val << 8); break; - case 0x7f06: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFF00FFFF) | (val << 16); break; - case 0x7f07: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00FFFFFF) | (val << 24); break; - case 0x7f08: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFFFF00) | val; break; - case 0x7f09: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFF00FF) | (val << 8); break; - case 0x7f0a: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFF00FFFF) | (val << 16); break; - case 0x7f0d: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00FFFFFF) | (val << 24); break; - case 0x7f13: et4000->mmu.ctrl=val; break; - } - break; - } -} - -uint8_t et4000w32p_mmu_read(uint32_t addr, void *p) -{ - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; - int bank; - uint8_t temp; - switch (addr & 0x6000) - { - case 0x0000: /*MMU 0*/ - case 0x2000: /*MMU 1*/ - case 0x4000: /*MMU 2*/ - bank = (addr >> 13) & 3; - if (et4000->mmu.ctrl & (1 << bank)) - { - et4000w32p_wait_fifo_idle(et4000); - temp = 0xff; - if (et4000->acl.cpu_dat_pos) - { - et4000->acl.cpu_dat_pos--; - temp = et4000->acl.cpu_dat & 0xff; - et4000->acl.cpu_dat >>= 8; - } - if ((et4000->acl.queued.ctrl_routing & 0x40) && !et4000->acl.cpu_dat_pos && !(et4000->acl.internal.ctrl_routing & 3)) - et4000w32_blit(4, ~0, 0, 0, et4000); - /*???*/ - return temp; - } - if ((addr&0x1fff) + et4000->mmu.base[bank] >= svga->vram_max) - return 0xff; - return svga->vram[(addr&0x1fff) + et4000->mmu.base[bank]]; - - case 0x6000: - if ((addr & 0x7fff) >= 0x7f80) - et4000w32p_wait_fifo_idle(et4000); - switch (addr&0x7fff) - { - case 0x7f00: return et4000->mmu.base[0]; - case 0x7f01: return et4000->mmu.base[0] >> 8; - case 0x7f02: return et4000->mmu.base[0] >> 16; - case 0x7f03: return et4000->mmu.base[0] >> 24; - case 0x7f04: return et4000->mmu.base[1]; - case 0x7f05: return et4000->mmu.base[1] >> 8; - case 0x7f06: return et4000->mmu.base[1] >> 16; - case 0x7f07: return et4000->mmu.base[1] >> 24; - case 0x7f08: return et4000->mmu.base[2]; - case 0x7f09: return et4000->mmu.base[2] >> 8; - case 0x7f0a: return et4000->mmu.base[2] >> 16; - case 0x7f0b: return et4000->mmu.base[2] >> 24; - case 0x7f13: return et4000->mmu.ctrl; - - case 0x7f36: - temp = et4000->acl.status; - temp &= ~0x03; - if (!FIFO_EMPTY) - temp |= 0x02; - if (FIFO_FULL) - temp |= 0x01; - return temp; - case 0x7f80: return et4000->acl.internal.pattern_addr; - case 0x7f81: return et4000->acl.internal.pattern_addr >> 8; - case 0x7f82: return et4000->acl.internal.pattern_addr >> 16; - case 0x7f83: return et4000->acl.internal.pattern_addr >> 24; - case 0x7f84: return et4000->acl.internal.source_addr; - case 0x7f85: return et4000->acl.internal.source_addr >> 8; - case 0x7f86: return et4000->acl.internal.source_addr >> 16; - case 0x7f87: return et4000->acl.internal.source_addr >> 24; - case 0x7f88: return et4000->acl.internal.pattern_off; - case 0x7f89: return et4000->acl.internal.pattern_off >> 8; - case 0x7f8a: return et4000->acl.internal.source_off; - case 0x7f8b: return et4000->acl.internal.source_off >> 8; - case 0x7f8c: return et4000->acl.internal.dest_off; - case 0x7f8d: return et4000->acl.internal.dest_off >> 8; - case 0x7f8e: return et4000->acl.internal.pixel_depth; - case 0x7f8f: return et4000->acl.internal.xy_dir; - case 0x7f90: return et4000->acl.internal.pattern_wrap; - case 0x7f92: return et4000->acl.internal.source_wrap; - case 0x7f98: return et4000->acl.internal.count_x; - case 0x7f99: return et4000->acl.internal.count_x >> 8; - case 0x7f9a: return et4000->acl.internal.count_y; - case 0x7f9b: return et4000->acl.internal.count_y >> 8; - case 0x7f9c: return et4000->acl.internal.ctrl_routing; - case 0x7f9d: return et4000->acl.internal.ctrl_reload; - case 0x7f9e: return et4000->acl.internal.rop_bg; - case 0x7f9f: return et4000->acl.internal.rop_fg; - case 0x7fa0: return et4000->acl.internal.dest_addr; - case 0x7fa1: return et4000->acl.internal.dest_addr >> 8; - case 0x7fa2: return et4000->acl.internal.dest_addr >> 16; - case 0x7fa3: return et4000->acl.internal.dest_addr >> 24; - } - return 0xff; - } - return 0xff; -} - -static int et4000w32_max_x[8]={0,0,4,8,16,32,64,0x70000000}; -static int et4000w32_wrap_x[8]={0,0,3,7,15,31,63,0xFFFFFFFF}; -static int et4000w32_wrap_y[8]={1,2,4,8,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; - -/* int bltout=0; */ -void et4000w32_blit_start(et4000w32p_t *et4000) -{ - if (!(et4000->acl.queued.xy_dir & 0x20)) - et4000->acl.internal.error = et4000->acl.internal.dmaj / 2; - et4000->acl.pattern_addr= et4000->acl.internal.pattern_addr; - et4000->acl.source_addr = et4000->acl.internal.source_addr; - et4000->acl.mix_addr = et4000->acl.internal.mix_addr; - et4000->acl.mix_back = et4000->acl.mix_addr; - et4000->acl.dest_addr = et4000->acl.internal.dest_addr; - et4000->acl.dest_back = et4000->acl.dest_addr; - et4000->acl.internal.pos_x = et4000->acl.internal.pos_y = 0; - et4000->acl.pattern_x = et4000->acl.source_x = et4000->acl.pattern_y = et4000->acl.source_y = 0; - et4000->acl.status |= ACL_XYST; - if ((!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) && !(et4000->acl.internal.ctrl_routing & 0x40)) - et4000->acl.status |= ACL_SSO; - - if (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]) - { - et4000->acl.pattern_x = et4000->acl.pattern_addr & et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; - et4000->acl.pattern_addr &= ~et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; - } - et4000->acl.pattern_back = et4000->acl.pattern_addr; - if (!(et4000->acl.internal.pattern_wrap & 0x40)) - { - et4000->acl.pattern_y = (et4000->acl.pattern_addr / (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); - et4000->acl.pattern_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) - 1); - } - et4000->acl.pattern_x_back = et4000->acl.pattern_x; - - if (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]) - { - et4000->acl.source_x = et4000->acl.source_addr & et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; - et4000->acl.source_addr &= ~et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; - } - et4000->acl.source_back = et4000->acl.source_addr; - if (!(et4000->acl.internal.source_wrap & 0x40)) - { - et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); - et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1); - } - et4000->acl.source_x_back = et4000->acl.source_x; - - et4000w32_max_x[2] = ((et4000->acl.internal.pixel_depth & 0x30) == 0x20) ? 3 : 4; - - et4000->acl.internal.count_x += (et4000->acl.internal.pixel_depth >> 4) & 3; - et4000->acl.cpu_dat_pos = 0; - et4000->acl.cpu_dat = 0; - - et4000->acl.pix_pos = 0; -} - -void et4000w32_incx(int c, et4000w32p_t *et4000) -{ - et4000->acl.dest_addr += c; - et4000->acl.pattern_x += c; - et4000->acl.source_x += c; - et4000->acl.mix_addr += c; - if (et4000->acl.pattern_x >= et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]) - et4000->acl.pattern_x -= et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]; - if (et4000->acl.source_x >= et4000w32_max_x[et4000->acl.internal.source_wrap & 7]) - et4000->acl.source_x -= et4000w32_max_x[et4000->acl.internal.source_wrap & 7]; -} -void et4000w32_decx(int c, et4000w32p_t *et4000) -{ - et4000->acl.dest_addr -= c; - et4000->acl.pattern_x -= c; - et4000->acl.source_x -= c; - et4000->acl.mix_addr -= c; - if (et4000->acl.pattern_x < 0) - et4000->acl.pattern_x += et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]; - if (et4000->acl.source_x < 0) - et4000->acl.source_x += et4000w32_max_x[et4000->acl.internal.source_wrap & 7]; -} -void et4000w32_incy(et4000w32p_t *et4000) -{ - et4000->acl.pattern_addr += et4000->acl.internal.pattern_off + 1; - et4000->acl.source_addr += et4000->acl.internal.source_off + 1; - et4000->acl.mix_addr += et4000->acl.internal.mix_off + 1; - et4000->acl.dest_addr += et4000->acl.internal.dest_off + 1; - et4000->acl.pattern_y++; - if (et4000->acl.pattern_y == et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) - { - et4000->acl.pattern_y = 0; - et4000->acl.pattern_addr = et4000->acl.pattern_back; - } - et4000->acl.source_y++; - if (et4000->acl.source_y == et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - { - et4000->acl.source_y = 0; - et4000->acl.source_addr = et4000->acl.source_back; - } -} -void et4000w32_decy(et4000w32p_t *et4000) -{ - et4000->acl.pattern_addr -= et4000->acl.internal.pattern_off + 1; - et4000->acl.source_addr -= et4000->acl.internal.source_off + 1; - et4000->acl.mix_addr -= et4000->acl.internal.mix_off + 1; - et4000->acl.dest_addr -= et4000->acl.internal.dest_off + 1; - et4000->acl.pattern_y--; - if (et4000->acl.pattern_y < 0 && !(et4000->acl.internal.pattern_wrap & 0x40)) - { - et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1; - et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1)); - } - et4000->acl.source_y--; - if (et4000->acl.source_y < 0 && !(et4000->acl.internal.source_wrap & 0x40)) - { - et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; - et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] *(et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1));; - } -} - -void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000) -{ - svga_t *svga = &et4000->svga; - int c,d; - uint8_t pattern, source, dest, out; - uint8_t rop; - int mixdat; - - if (!(et4000->acl.status & ACL_XYST)) return; - if (et4000->acl.internal.xy_dir & 0x80) /*Line draw*/ - { - while (count--) - { - et4000w32_log("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); - pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff]; - source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff]; - et4000w32_log("%06X %06X ", (et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff, (et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff); - if (cpu_input == 2) - { - source = sdat & 0xff; - sdat >>= 8; - } - dest = svga->vram[et4000->acl.dest_addr & 0x1fffff]; - out = 0; - et4000w32_log("%06X ", et4000->acl.dest_addr); - if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) - { - mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff] & (1 << (et4000->acl.mix_addr & 7)); - et4000w32_log("%06X %02X ", et4000->acl.mix_addr, svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff]); - } - else - { - mixdat = mix & 1; - mix >>= 1; - mix |= 0x80000000; - } - et4000->acl.mix_addr++; - rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; - for (c = 0; c < 8; c++) - { - d = (dest & (1 << c)) ? 1 : 0; - if (source & (1 << c)) d |= 2; - if (pattern & (1 << c)) d |= 4; - if (rop & (1 << d)) out |= (1 << c); - } - et4000w32_log("%06X = %02X\n", et4000->acl.dest_addr & 0x1fffff, out); - if (!(et4000->acl.internal.ctrl_routing & 0x40)) - { - svga->vram[et4000->acl.dest_addr & 0x1fffff] = out; - svga->changedvram[(et4000->acl.dest_addr & 0x1fffff) >> 12] = changeframecount; - } - else - { - et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8)); - et4000->acl.cpu_dat_pos++; - } - - et4000->acl.pix_pos++; - et4000->acl.internal.pos_x++; - if (et4000->acl.pix_pos <= ((et4000->acl.internal.pixel_depth >> 4) & 3)) - { - if (et4000->acl.internal.xy_dir & 1) et4000w32_decx(1, et4000); - else et4000w32_incx(1, et4000); - } - else - { - if (et4000->acl.internal.xy_dir & 1) - et4000w32_incx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000); - else - et4000w32_decx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000); - et4000->acl.pix_pos = 0; - /*Next pixel*/ - switch (et4000->acl.internal.xy_dir & 7) - { - case 0: case 1: /*Y+*/ - et4000w32_incy(et4000); - et4000->acl.internal.pos_y++; - et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1; - break; - case 2: case 3: /*Y-*/ - et4000w32_decy(et4000); - et4000->acl.internal.pos_y++; - et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1; - break; - case 4: case 6: /*X+*/ - et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - break; - case 5: case 7: /*X-*/ - et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - break; - } - et4000->acl.internal.error += et4000->acl.internal.dmin; - if (et4000->acl.internal.error > et4000->acl.internal.dmaj) - { - et4000->acl.internal.error -= et4000->acl.internal.dmaj; - switch (et4000->acl.internal.xy_dir & 7) - { - case 0: case 2: /*X+*/ - et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - et4000->acl.internal.pos_x++; - break; - case 1: case 3: /*X-*/ - et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - et4000->acl.internal.pos_x++; - break; - case 4: case 5: /*Y+*/ - et4000w32_incy(et4000); - et4000->acl.internal.pos_y++; - break; - case 6: case 7: /*Y-*/ - et4000w32_decy(et4000); - et4000->acl.internal.pos_y++; - break; - } - } - if (et4000->acl.internal.pos_x > et4000->acl.internal.count_x || - et4000->acl.internal.pos_y > et4000->acl.internal.count_y) - { - et4000->acl.status &= ~(ACL_XYST | ACL_SSO); - return; - } - } - } - } - else - { - while (count--) - { - et4000w32_log("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); - - pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff]; - source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff]; - et4000w32_log("%i %06X %06X %02X %02X ", et4000->acl.pattern_y, (et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff, (et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff, pattern, source); - - if (cpu_input == 2) - { - source = sdat & 0xff; - sdat >>= 8; - } - dest = svga->vram[et4000->acl.dest_addr & 0x1fffff]; - out = 0; - et4000w32_log("%06X %02X %i %08X %08X ", dest, et4000->acl.dest_addr, mix & 1, mix, et4000->acl.mix_addr); - if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) - { - mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff] & (1 << (et4000->acl.mix_addr & 7)); - et4000w32_log("%06X %02X ", et4000->acl.mix_addr, svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff]); - } - else - { - mixdat = mix & 1; - mix >>= 1; - mix |= 0x80000000; - } - - rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; - for (c = 0; c < 8; c++) - { - d = (dest & (1 << c)) ? 1 : 0; - if (source & (1 << c)) d |= 2; - if (pattern & (1 << c)) d |= 4; - if (rop & (1 << d)) out |= (1 << c); - } - et4000w32_log("%06X = %02X\n", et4000->acl.dest_addr & 0x1fffff, out); - if (!(et4000->acl.internal.ctrl_routing & 0x40)) - { - svga->vram[et4000->acl.dest_addr & 0x1fffff] = out; - svga->changedvram[(et4000->acl.dest_addr & 0x1fffff) >> 12] = changeframecount; - } - else - { - et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8)); - et4000->acl.cpu_dat_pos++; - } - - if (et4000->acl.internal.xy_dir & 1) et4000w32_decx(1, et4000); - else et4000w32_incx(1, et4000); - - et4000->acl.internal.pos_x++; - if (et4000->acl.internal.pos_x > et4000->acl.internal.count_x) - { - if (et4000->acl.internal.xy_dir & 2) - { - et4000w32_decy(et4000); - et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back - (et4000->acl.internal.mix_off + 1); - et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); - } - else - { - et4000w32_incy(et4000); - et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back + et4000->acl.internal.mix_off + 1; - et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1; - } - - et4000->acl.pattern_x = et4000->acl.pattern_x_back; - et4000->acl.source_x = et4000->acl.source_x_back; - - et4000->acl.internal.pos_y++; - et4000->acl.internal.pos_x = 0; - if (et4000->acl.internal.pos_y > et4000->acl.internal.count_y) - { - et4000->acl.status &= ~(ACL_XYST | ACL_SSO); - return; - } - if (cpu_input) return; - if (et4000->acl.internal.ctrl_routing & 0x40) - { - if (et4000->acl.cpu_dat_pos & 3) - et4000->acl.cpu_dat_pos += 4 - (et4000->acl.cpu_dat_pos & 3); - return; - } - } - } - } -} - - -void et4000w32p_hwcursor_draw(svga_t *svga, int displine) -{ - int x, offset; - uint8_t dat; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - offset = svga->hwcursor_latch.xoff; - - for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) - { - dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 32] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 32] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 33 + x_add] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 33 + x_add] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 34] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 34] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 35] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 35] ^= 0xFFFFFF; - dat >>= 2; - offset += 4; - } - svga->hwcursor_latch.addr += 16; -} - -static void et4000w32p_io_remove(et4000w32p_t *et4000) -{ - io_removehandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - - io_removehandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); -} - -static void et4000w32p_io_set(et4000w32p_t *et4000) -{ - et4000w32p_io_remove(et4000); - - io_sethandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - - io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); -} - -uint8_t et4000w32p_pci_read(int func, int addr, void *p) -{ - et4000w32p_t *et4000 = (et4000w32p_t *)p; - - addr &= 0xff; - - switch (addr) - { - case 0x00: return 0x0c; /*Tseng Labs*/ - case 0x01: return 0x10; - - case 0x02: return 0x06; /*ET4000W32p Rev D*/ - case 0x03: return 0x32; - - case PCI_REG_COMMAND: - return et4000->pci_regs[PCI_REG_COMMAND] | 0x80; /*Respond to IO and memory accesses*/ - - case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ - - case 0x08: return 0; /*Revision ID*/ - case 0x09: return 0; /*Programming interface*/ - - case 0x0a: return 0x00; /*Supports VGA interface, XGA compatible*/ - case 0x0b: return is_pentium ? 0x03 : 0x00; /* This has to be done in order to make this card work with the two 486 PCI machines. */ - - case 0x10: return 0x00; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: return 0x00; - case 0x13: return (et4000->linearbase >> 24); - - case 0x30: return et4000->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return 0x00; - case 0x33: return (et4000->pci_regs[0x33]) & 0xf0; - - } - return 0; -} - -void et4000w32p_pci_write(int func, int addr, uint8_t val, void *p) -{ - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; - - addr &= 0xff; - - switch (addr) - { - case PCI_REG_COMMAND: - et4000->pci_regs[PCI_REG_COMMAND] = (val & 0x23) | 0x80; - if (val & PCI_COMMAND_IO) - et4000w32p_io_set(et4000); - else - et4000w32p_io_remove(et4000); - et4000w32p_recalcmapping(et4000); - break; - - case 0x13: - et4000->linearbase &= 0x00c00000; - et4000->linearbase = (et4000->pci_regs[0x13] << 24); - svga->crtc[0x30] &= 3; - svga->crtc[0x30] = ((et4000->linearbase & 0x3f000000) >> 22); - et4000w32p_recalcmapping(et4000); - break; - - case 0x30: case 0x31: case 0x32: case 0x33: - et4000->pci_regs[addr] = val; - et4000->pci_regs[0x30] = 1; - et4000->pci_regs[0x31] = 0; - et4000->pci_regs[0x32] = 0; - et4000->pci_regs[0x33] &= 0xf0; - if (et4000->pci_regs[0x30] & 0x01) - { - uint32_t addr = (et4000->pci_regs[0x33] << 24); - if (!addr) - { - addr = 0xC0000; - } - et4000w32_log("ET4000 bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&et4000->bios_rom.mapping, addr, 0x8000); - } - else - { - et4000w32_log("ET4000 bios_rom disabled\n"); - mem_mapping_disable(&et4000->bios_rom.mapping); - } - return; - } -} - -void *et4000w32p_init(const device_t *info) -{ - int vram_size; - et4000w32p_t *et4000 = malloc(sizeof(et4000w32p_t)); - memset(et4000, 0, sizeof(et4000w32p_t)); - - vram_size = device_get_config_int("memory"); - - et4000->interleaved = (vram_size == 2) ? 1 : 0; - - svga_init(&et4000->svga, et4000, vram_size << 20, - et4000w32p_recalctimings, - et4000w32p_in, et4000w32p_out, - et4000w32p_hwcursor_draw, - NULL); - - et4000->type = info->local; - - switch(et4000->type) { - case ET4000W32_CARDEX: - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_CARDEX, 0xc0000, 0x8000, 0x7fff, 0, - MEM_MAPPING_EXTERNAL); - break; -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) - case ET4000W32_DIAMOND: - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_DIAMOND, 0xc0000, 0x8000, 0x7fff, 0, - MEM_MAPPING_EXTERNAL); - break; -#endif - } - et4000->pci = !!(info->flags & DEVICE_PCI); - if (info->flags & DEVICE_PCI) - mem_mapping_disable(&et4000->bios_rom.mapping); - - mem_mapping_add(&et4000->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &et4000->svga); - mem_mapping_add(&et4000->mmu_mapping, 0, 0, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL, 0, et4000); - - et4000w32p_io_set(et4000); - - if (info->flags & DEVICE_PCI) - pci_add_card(PCI_ADD_VIDEO, et4000w32p_pci_read, et4000w32p_pci_write, et4000); - - /* Hardwired bits: 00000000 1xx0x0xx */ - /* R/W bits: xx xxxx */ - /* PCem bits: 111 */ - et4000->pci_regs[0x04] = 0x83; - - et4000->pci_regs[0x10] = 0x00; - et4000->pci_regs[0x11] = 0x00; - et4000->pci_regs[0x12] = 0xff; - et4000->pci_regs[0x13] = 0xff; - - et4000->pci_regs[0x30] = 0x00; - et4000->pci_regs[0x31] = 0x00; - et4000->pci_regs[0x32] = 0x00; - et4000->pci_regs[0x33] = 0xf0; - - et4000->wake_fifo_thread = thread_create_event(); - et4000->fifo_not_full_event = thread_create_event(); - et4000->fifo_thread = thread_create(fifo_thread, et4000); - - return et4000; -} - -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) -int et4000w32p_available(void) -{ - return rom_present(BIOS_ROM_PATH_DIAMOND); -} -#endif - -int et4000w32p_cardex_available(void) -{ - return rom_present(BIOS_ROM_PATH_CARDEX); -} - -void et4000w32p_close(void *p) -{ - et4000w32p_t *et4000 = (et4000w32p_t *)p; - - svga_close(&et4000->svga); - - thread_kill(et4000->fifo_thread); - thread_destroy_event(et4000->wake_fifo_thread); - thread_destroy_event(et4000->fifo_not_full_event); - - free(et4000); -} - -void et4000w32p_speed_changed(void *p) -{ - et4000w32p_t *et4000 = (et4000w32p_t *)p; - - svga_recalctimings(&et4000->svga); -} - -void et4000w32p_force_redraw(void *p) -{ - et4000w32p_t *et4000w32p = (et4000w32p_t *)p; - - et4000w32p->svga.fullchange = changeframecount; -} - -static const device_config_t et4000w32p_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 2, - { - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -const device_t et4000w32p_cardex_vlb_device = -{ - "Tseng Labs ET4000/w32p VLB (Cardex)", - DEVICE_VLB, ET4000W32_CARDEX, - et4000w32p_init, et4000w32p_close, NULL, - et4000w32p_cardex_available, - et4000w32p_speed_changed, - et4000w32p_force_redraw, - et4000w32p_config -}; - -const device_t et4000w32p_cardex_pci_device = -{ - "Tseng Labs ET4000/w32p PCI (Cardex)", - DEVICE_PCI, ET4000W32_CARDEX, - et4000w32p_init, et4000w32p_close, NULL, - et4000w32p_cardex_available, - et4000w32p_speed_changed, - et4000w32p_force_redraw, - et4000w32p_config -}; - -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) -const device_t et4000w32p_vlb_device = -{ - "Tseng Labs ET4000/w32p VLB (Diamond)", - DEVICE_VLB, ET4000W32_DIAMOND, - et4000w32p_init, et4000w32p_close, NULL, - et4000w32p_available, - et4000w32p_speed_changed, - et4000w32p_force_redraw, - et4000w32p_config -}; - -const device_t et4000w32p_pci_device = -{ - "Tseng Labs ET4000/w32p PCI (Diamond)", - DEVICE_PCI, ET4000W32_DIAMOND, - et4000w32p_init, et4000w32p_close, NULL, - et4000w32p_available, - et4000w32p_speed_changed, - et4000w32p_force_redraw, - et4000w32p_config -}; -#endif diff --git a/backup code/video - Cópia/vid_et4000w32.h b/backup code/video - Cópia/vid_et4000w32.h deleted file mode 100644 index 80a14e5d4..000000000 --- a/backup code/video - Cópia/vid_et4000w32.h +++ /dev/null @@ -1,7 +0,0 @@ -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) -extern const device_t et4000w32p_vlb_device; -extern const device_t et4000w32p_pci_device; -#endif - -extern const device_t et4000w32p_cardex_vlb_device; -extern const device_t et4000w32p_cardex_pci_device; diff --git a/backup code/video - Cópia/vid_et4000w32i.c b/backup code/video - Cópia/vid_et4000w32i.c deleted file mode 100644 index f77055e37..000000000 --- a/backup code/video - Cópia/vid_et4000w32i.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * 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. - * - * The below is (with some removals) a reasonable emulation - * of the ET4000/W32i blitter. Unfortunately the Diamond - * Stealth 32 is actually an ET4000/W32p! Which has a different - * blitter. If only I'd dug out and looked at the card before - * trying to emulate it. - * - * This might be of use for an attempt at an ET4000/W32i. - * - * Version: @(#)vid_et4000w32i.c 1.0.2 2017/11/04 - * - * Author: Sarah Walker, - * - * Copyright 2008-2017 Sarah Walker. - */ -#if 0 - -#include -#include -#include -#include -#include "../86box.h" - -int et4k_b8000; - -struct -{ - struct - { - uint32_t pattern_addr,source_addr,dest_addr; - uint16_t pattern_off,source_off,dest_off; - uint8_t vbus,xy_dir; - uint8_t pattern_wrap,source_wrap; - uint16_t count_x,count_y; - uint8_t ctrl_routing,ctrl_reload; - uint8_t rop_fg,rop_bg; - uint16_t pos_x,pos_y; - } queued,internal; - uint32_t pattern_addr,source_addr,dest_addr; - uint32_t pattern_back,dest_back; - int pattern_x,source_x; - int pattern_x_back; - int pattern_y,source_y; - uint8_t status; - uint32_t cpu_input; - int cpu_input_num; -} acl; - -#define ACL_WRST 1 -#define ACL_RDST 2 -#define ACL_XYST 4 -#define ACL_SSO 8 - -struct -{ - uint32_t base[3]; - uint8_t ctrl; -} mmu; - -void et4000w32_reset() -{ - acl.status=0; - acl.cpu_input_num=0; -} - -void et4000w32_blit_start(); -void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input); - -int et4000w32_vbus[4]={1,2,4,4}; - -void et4000w32_mmu_write(uint32_t addr, uint8_t val) -{ - int bank; - pclog("ET4K write %08X %02X %i %02X %02X %04X(%08X):%08X %04X %04X %02X %08X\n",addr,val,acl.cpu_input_num,acl.status,acl.internal.ctrl_routing,CS,cs,pc,CS,DI,mmu.ctrl,mmu.base[2]); - switch (addr&0x6000) - { - case 0x0000: /*MMU 0*/ - case 0x2000: /*MMU 1*/ - case 0x4000: /*MMU 2*/ - bank=(addr>>13)&3; - if (mmu.ctrl&(1<>12]=changeframecount; - } - break; - case 0x6000: - switch (addr&0x7FFF) - { - case 0x7F00: mmu.base[0]=(mmu.base[0]&0xFFFFFF00)|val; break; - case 0x7F01: mmu.base[0]=(mmu.base[0]&0xFFFF00FF)|(val<<8); break; - case 0x7F02: mmu.base[0]=(mmu.base[0]&0xFF00FFFF)|(val<<16); break; - case 0x7F03: mmu.base[0]=(mmu.base[0]&0x00FFFFFF)|(val<<24); break; - case 0x7F04: mmu.base[1]=(mmu.base[1]&0xFFFFFF00)|val; break; - case 0x7F05: mmu.base[1]=(mmu.base[1]&0xFFFF00FF)|(val<<8); break; - case 0x7F06: mmu.base[1]=(mmu.base[1]&0xFF00FFFF)|(val<<16); break; - case 0x7F07: mmu.base[1]=(mmu.base[1]&0x00FFFFFF)|(val<<24); break; - case 0x7F08: mmu.base[2]=(mmu.base[2]&0xFFFFFF00)|val; break; - case 0x7F09: mmu.base[2]=(mmu.base[2]&0xFFFF00FF)|(val<<8); break; - case 0x7F0A: mmu.base[2]=(mmu.base[2]&0xFF00FFFF)|(val<<16); break; - case 0x7F0B: mmu.base[2]=(mmu.base[2]&0x00FFFFFF)|(val<<24); break; - case 0x7F13: mmu.ctrl=val; break; - - case 0x7F80: acl.queued.pattern_addr=(acl.queued.pattern_addr&0xFFFFFF00)|val; break; - case 0x7F81: acl.queued.pattern_addr=(acl.queued.pattern_addr&0xFFFF00FF)|(val<<8); break; - case 0x7F82: acl.queued.pattern_addr=(acl.queued.pattern_addr&0xFF00FFFF)|(val<<16); break; - case 0x7F83: acl.queued.pattern_addr=(acl.queued.pattern_addr&0x00FFFFFF)|(val<<24); break; - case 0x7F84: acl.queued.source_addr =(acl.queued.source_addr &0xFFFFFF00)|val; break; - case 0x7F85: acl.queued.source_addr =(acl.queued.source_addr &0xFFFF00FF)|(val<<8); break; - case 0x7F86: acl.queued.source_addr =(acl.queued.source_addr &0xFF00FFFF)|(val<<16); break; - case 0x7F87: acl.queued.source_addr =(acl.queued.source_addr &0x00FFFFFF)|(val<<24); break; - case 0x7F88: acl.queued.pattern_off=(acl.queued.pattern_off&0xFF00)|val; break; - case 0x7F89: acl.queued.pattern_off=(acl.queued.pattern_off&0x00FF)|(val<<8); break; - case 0x7F8A: acl.queued.source_off =(acl.queued.source_off &0xFF00)|val; break; - case 0x7F8B: acl.queued.source_off =(acl.queued.source_off &0x00FF)|(val<<8); break; - case 0x7F8C: acl.queued.dest_off =(acl.queued.dest_off &0xFF00)|val; break; - case 0x7F8D: acl.queued.dest_off =(acl.queued.dest_off &0x00FF)|(val<<8); break; - case 0x7F8E: acl.queued.vbus=val; break; - case 0x7F8F: acl.queued.xy_dir=val; break; - case 0x7F90: acl.queued.pattern_wrap=val; break; - case 0x7F92: acl.queued.source_wrap=val; break; - case 0x7F98: acl.queued.count_x =(acl.queued.count_x &0xFF00)|val; break; - case 0x7F99: acl.queued.count_x =(acl.queued.count_x &0x00FF)|(val<<8); break; - case 0x7F9A: acl.queued.count_y =(acl.queued.count_y &0xFF00)|val; break; - case 0x7F9B: acl.queued.count_y =(acl.queued.count_y &0x00FF)|(val<<8); break; - case 0x7F9C: acl.queued.ctrl_routing=val; break; - case 0x7F9D: acl.queued.ctrl_reload =val; break; - case 0x7F9E: acl.queued.rop_bg =val; break; - case 0x7F9F: acl.queued.rop_fg =val; break; - case 0x7FA0: acl.queued.dest_addr =(acl.queued.dest_addr &0xFFFFFF00)|val; break; - case 0x7FA1: acl.queued.dest_addr =(acl.queued.dest_addr &0xFFFF00FF)|(val<<8); break; - case 0x7FA2: acl.queued.dest_addr =(acl.queued.dest_addr &0xFF00FFFF)|(val<<16); break; - case 0x7FA3: acl.queued.dest_addr =(acl.queued.dest_addr &0x00FFFFFF)|(val<<24); - acl.internal=acl.queued; - et4000w32_blit_start(); - acl.cpu_input_num=0; - if (!(acl.queued.ctrl_routing&0x37)) - { - et4000w32_blit(0xFFFFFF, ~0, 0, 0); - } - break; - } - break; - } -} - -uint8_t et4000w32_mmu_read(uint32_t addr) -{ - int bank; - pclog("ET4K read %08X %04X(%08X):%08X\n",addr,CS,cs,pc); - switch (addr&0x6000) - { - case 0x0000: /*MMU 0*/ - case 0x2000: /*MMU 1*/ - case 0x4000: /*MMU 2*/ - bank=(addr>>13)&3; - if (mmu.ctrl&(1<>8; - case 0x7F02: return mmu.base[0]>>16; - case 0x7F03: return mmu.base[0]>>24; - case 0x7F04: return mmu.base[1]; - case 0x7F05: return mmu.base[1]>>8; - case 0x7F06: return mmu.base[1]>>16; - case 0x7F07: return mmu.base[1]>>24; - case 0x7F08: return mmu.base[2]; - case 0x7F09: return mmu.base[2]>>8; - case 0x7F0A: return mmu.base[2]>>16; - case 0x7F0B: return mmu.base[2]>>24; - case 0x7F13: return mmu.ctrl; - - case 0x7F36: -// if (acl.internal.pos_x!=acl.internal.count_x || acl.internal.pos_y!=acl.internal.count_y) return acl.status | ACL_XYST; - return acl.status & ~(ACL_XYST | ACL_SSO); - case 0x7F80: return acl.internal.pattern_addr; - case 0x7F81: return acl.internal.pattern_addr>>8; - case 0x7F82: return acl.internal.pattern_addr>>16; - case 0x7F83: return acl.internal.pattern_addr>>24; - case 0x7F84: return acl.internal.source_addr; - case 0x7F85: return acl.internal.source_addr>>8; - case 0x7F86: return acl.internal.source_addr>>16; - case 0x7F87: return acl.internal.source_addr>>24; - case 0x7F88: return acl.internal.pattern_off; - case 0x7F89: return acl.internal.pattern_off>>8; - case 0x7F8A: return acl.internal.source_off; - case 0x7F8B: return acl.internal.source_off>>8; - case 0x7F8C: return acl.internal.dest_off; - case 0x7F8D: return acl.internal.dest_off>>8; - case 0x7F8E: return acl.internal.vbus; - case 0x7F8F: return acl.internal.xy_dir; - case 0x7F90: return acl.internal.pattern_wrap; - case 0x7F92: return acl.internal.source_wrap; - case 0x7F98: return acl.internal.count_x; - case 0x7F99: return acl.internal.count_x>>8; - case 0x7F9A: return acl.internal.count_y; - case 0x7F9B: return acl.internal.count_y>>8; - case 0x7F9C: return acl.internal.ctrl_routing; - case 0x7F9D: return acl.internal.ctrl_reload; - case 0x7F9E: return acl.internal.rop_bg; - case 0x7F9F: return acl.internal.rop_fg; - case 0x7FA0: return acl.internal.dest_addr; - case 0x7FA1: return acl.internal.dest_addr>>8; - case 0x7FA2: return acl.internal.dest_addr>>16; - case 0x7FA3: return acl.internal.dest_addr>>24; - } - return 0xFF; - } -} - -int et4000w32_wrap_x[8]={0,0,3,7,15,31,63,0xFFFFFFFF}; -int et4000w32_wrap_y[8]={1,2,4,8,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; - -void et4000w32_blit_start() -{ - pclog("Blit - %08X %08X %08X (%i,%i) %i %i %i %02X %02X %02X\n",acl.internal.pattern_addr,acl.internal.source_addr,acl.internal.dest_addr,acl.internal.dest_addr%640,acl.internal.dest_addr/640,acl.internal.xy_dir,acl.internal.count_x,acl.internal.count_y,acl.internal.rop_fg,acl.internal.rop_bg, acl.internal.ctrl_routing); - acl.pattern_addr=acl.internal.pattern_addr; - acl.source_addr =acl.internal.source_addr; - acl.dest_addr =acl.internal.dest_addr; - acl.dest_back =acl.dest_addr; - acl.internal.pos_x=acl.internal.pos_y=0; - acl.pattern_x=acl.source_x=acl.pattern_y=acl.source_y=0; - acl.status = ACL_XYST; - if (!(acl.internal.ctrl_routing&7) || (acl.internal.ctrl_routing&4)) acl.status |= ACL_SSO; - if (et4000w32_wrap_x[acl.internal.pattern_wrap&7]) - { - acl.pattern_x=acl.pattern_addr&et4000w32_wrap_x[acl.internal.pattern_wrap&7]; - acl.pattern_addr&=~et4000w32_wrap_x[acl.internal.pattern_wrap&7]; - } - if (!(acl.internal.pattern_wrap&0x80)) - { - acl.pattern_y=(acl.pattern_addr/(et4000w32_wrap_x[acl.internal.pattern_wrap&7]+1))&(et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7]-1); - acl.pattern_addr&=~(((et4000w32_wrap_x[acl.internal.pattern_wrap&7]+1)*et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7])-1); - } - acl.pattern_x_back=acl.pattern_x; - acl.pattern_back=acl.pattern_addr; -} - -void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input) -{ - int c,d; - uint8_t pattern,source,dest,out; - uint8_t rop; - -// if (count>400) pclog("New blit - %i,%i %06X (%i,%i) %06X %06X\n",acl.internal.count_x,acl.internal.count_y,acl.dest_addr,acl.dest_addr%640,acl.dest_addr/640,acl.source_addr,acl.pattern_addr); -// pclog("Blit exec - %i %i %i\n",count,acl.internal.pos_x,acl.internal.pos_y); - while (count--) - { - pclog("%i,%i : ",acl.internal.pos_x,acl.internal.pos_y); - if (acl.internal.xy_dir&1) - { - pattern=vram[(acl.pattern_addr-acl.pattern_x)&0x1FFFFF]; - source =vram[(acl.source_addr -acl.source_x) &0x1FFFFF]; - pclog("%06X %06X ",(acl.pattern_addr-acl.pattern_x)&0x1FFFFF,(acl.source_addr -acl.source_x) &0x1FFFFF); - } - else - { - pattern=vram[(acl.pattern_addr+acl.pattern_x)&0x1FFFFF]; - source =vram[(acl.source_addr +acl.source_x) &0x1FFFFF]; - pclog("%06X %06X ",(acl.pattern_addr+acl.pattern_x)&0x1FFFFF,(acl.source_addr +acl.source_x) &0x1FFFFF); - } - if (cpu_input==2) - { - source=sdat&0xFF; - sdat>>=8; - } - dest=vram[acl.dest_addr &0x1FFFFF]; - out=0; - pclog("%06X %i %08X ",acl.dest_addr,mix&1,mix); - rop = (mix & 1) ? acl.internal.rop_fg:acl.internal.rop_bg; - mix>>=1; mix|=0x80000000; - for (c=0;c<8;c++) - { - d=(dest & (1<>12]=changeframecount; - - acl.pattern_x++; - acl.pattern_x&=et4000w32_wrap_x[acl.internal.pattern_wrap&7]; - acl.source_x++; - acl.source_x &=et4000w32_wrap_x[acl.internal.source_wrap&7]; - if (acl.internal.xy_dir&1) acl.dest_addr--; - else acl.dest_addr++; - - acl.internal.pos_x++; - if (acl.internal.pos_x>acl.internal.count_x) - { - if (acl.internal.xy_dir&2) - { - acl.pattern_addr-=(acl.internal.pattern_off+1); - acl.source_addr -=(acl.internal.source_off +1); - acl.dest_back=acl.dest_addr=acl.dest_back-(acl.internal.dest_off+1); - } - else - { - acl.pattern_addr+=acl.internal.pattern_off+1; - acl.source_addr +=acl.internal.source_off +1; - acl.dest_back=acl.dest_addr=acl.dest_back+acl.internal.dest_off+1; - } - acl.pattern_x = acl.pattern_x_back; - acl.source_x = 0; - acl.pattern_y++; - if (acl.pattern_y==et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7]) - { - acl.pattern_y=0; - acl.pattern_addr=acl.pattern_back; - } - acl.source_y++; - if (acl.source_y ==et4000w32_wrap_y[(acl.internal.source_wrap >>4)&7]) - { - acl.source_y=0; - acl.source_addr=acl.internal.source_addr; - } - - acl.internal.pos_y++; - if (acl.internal.pos_y>acl.internal.count_y) - { - acl.status = 0; - return; - } - acl.internal.pos_x=0; - if (cpu_input) return; - } - } -} - -/* for (y=0;y<=acl.internal.count_y;y++) - { - dest_back=acl.dest_addr; - for (x=0;x<=acl.internal.count_x;x++) - { - if (acl.internal.xy_dir&1) - { - pattern=vram[(acl.pattern_addr-pattern_x)&0x1FFFFF]; - source =vram[(acl.source_addr -source_x) &0x1FFFFF]; - } - else - { - pattern=vram[(acl.pattern_addr+pattern_x)&0x1FFFFF]; - source =vram[(acl.source_addr +source_x) &0x1FFFFF]; - } - dest=vram[acl.dest_addr &0x1FFFFF]; - out=0; - for (c=0;c<8;c++) - { - d=(dest&(1<>12]=changeframecount; - - pattern_x++; - pattern_x&=et4000w32_wrap_x[acl.internal.pattern_wrap&7]; - source_x++; - source_x &=et4000w32_wrap_x[acl.internal.source_wrap&7]; - if (acl.internal.xy_dir&1) acl.dest_addr--; - else acl.dest_addr++; - } - acl.pattern_addr+=acl.internal.pattern_off+1; - acl.source_addr +=acl.internal.source_off+1; - acl.dest_addr=dest_back+acl.internal.dest_off+1; - pattern_y++; - if (pattern_y==et4000w32_wrap_y[(acl.internal.pattern_wrap>>4)&7]) - { - pattern_y=0; - acl.pattern_addr=acl.internal.pattern_addr; - } - source_y++; - if (source_y ==et4000w32_wrap_y[(acl.internal.source_wrap >>4)&7]) - { - source_y=0; - acl.source_addr=acl.internal.source_addr; - } - }*/ - -#endif diff --git a/backup code/video - Cópia/vid_genius.c b/backup code/video - Cópia/vid_genius.c deleted file mode 100644 index 91d1bce61..000000000 --- a/backup code/video - Cópia/vid_genius.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - * 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. - * - * MDSI Genius VHR emulation. - * - * Version: @(#)vid_genius.c 1.0.10 2018/05/20 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../plat.h" -#include "video.h" -#include "vid_genius.h" - - -#define BIOS_ROM_PATH L"roms/video/genius/8x12.bin" - - -#define GENIUS_XSIZE 728 -#define GENIUS_YSIZE 1008 - - -extern uint8_t fontdat8x12[256][16]; - - -/* I'm at something of a disadvantage writing this emulation: I don't have an - * MDSI Genius card, nor do I have the BIOS extension (VHRBIOS.SYS) that came - * with it. What I do have are the GEM and Windows 1.04 drivers, plus a driver - * for a later MCA version of the card. The latter can be found at - * and is necessary if you - * want the Windows driver to work. - * - * This emulation appears to work correctly with: - * The MCA drivers GMC_ANSI.SYS and INS_ANSI.SYS - * The GEM driver SDGEN9.VGA - * The Windows 1.04 driver GENIUS.DRV - * - * As far as I can see, the card uses a fixed resolution of 728x1008 pixels. - * It has the following modes of operation: - * - * > MDA-compatible: 80x25 text, each character 9x15 pixels. - * > CGA-compatible: 640x200 mono graphics - * > Dual: MDA text in the top half, CGA graphics in the bottom - * > Native text: 80x66 text, each character 9x15 pixels. - * > Native graphics: 728x1008 mono graphics. - * - * Under the covers, this seems to translate to: - * > Text framebuffer. At B000:0000, 16k. Displayed if enable bit is set - * in the MDA control register. - * > Graphics framebuffer. In native modes goes from A000:0000 to A000:FFFF - * and B800:0000 to B800:FFFF. In CGA-compatible - * mode only the section at B800:0000 to B800:7FFF - * is visible. Displayed if enable bit is set in the - * CGA control register. - * - * Two card-specific registers control text and graphics display: - * - * 03B0: Control register. - * Bit 0: Map all graphics framebuffer into memory. - * Bit 2: Unknown. Set by GMC /M; cleared by mode set or GMC /T. - * Bit 4: Set for CGA-compatible graphics, clear for native graphics. - * Bit 5: Set for black on white, clear for white on black. - * - * 03B1: Character height register. - * Bits 0-1: Character cell height (0 => 15, 1 => 14, 2 => 13, 3 => 12) - * Bit 4: Set to double character cell height (scanlines are doubled) - * Bit 7: Unknown, seems to be set for all modes except 80x66 - * - * Not having the card also means I don't have its font. According to the - * card brochure the font is an 8x12 bitmap in a 9x15 character cell. I - * therefore generated it by taking the MDA font, increasing graphics to - * 16 pixels in height and reducing the height of characters so they fit - * in an 8x12 cell if necessary. - */ - - - -typedef struct genius_t -{ - mem_mapping_t mapping; - - uint8_t mda_crtc[32]; /* The 'CRTC' as the host PC sees it */ - int mda_crtcreg; /* Current CRTC register */ - uint8_t genius_control; /* Native control register - * I think bit 0 enables the full - * framebuffer. - */ - uint8_t genius_charh; /* Native character height register: - * 00h => chars are 15 pixels high - * 81h => chars are 14 pixels high - * 83h => chars are 12 pixels high - * 90h => chars are 30 pixels high [15 x 2] - * 93h => chars are 24 pixels high [12 x 2] - */ - uint8_t genius_mode; /* Current mode (see list at top of file) */ - uint8_t cga_ctrl; /* Emulated CGA control register */ - uint8_t mda_ctrl; /* Emulated MDA control register */ - uint8_t cga_colour; /* Emulated CGA colour register (ignored) */ - - uint8_t mda_stat; /* MDA status (IN 0x3BA) */ - uint8_t cga_stat; /* CGA status (IN 0x3DA) */ - - int font; /* Current font, 0 or 1 */ - int enabled; /* Display enabled, 0 or 1 */ - int detach; /* Detach cursor, 0 or 1 */ - - int64_t dispontime, dispofftime; - int64_t vidtime; - - int linepos, displine; - int vc; - int dispon, blink; - int64_t vsynctime; - - uint8_t *vram; -} genius_t; - -static uint32_t genius_pal[4]; - -/* Mapping of attributes to colours, in MDA emulation mode */ -static int mdacols[256][2][2]; - -void genius_recalctimings(genius_t *genius); -void genius_write(uint32_t addr, uint8_t val, void *p); -uint8_t genius_read(uint32_t addr, void *p); - - -void genius_out(uint16_t addr, uint8_t val, void *p) -{ - genius_t *genius = (genius_t *)p; - - switch (addr) - { - case 0x3b0: /* Command / control register */ - genius->genius_control = val; - if (val & 1) - { - mem_mapping_set_addr(&genius->mapping, 0xa0000, 0x28000); - } - else - { - mem_mapping_set_addr(&genius->mapping, 0xb0000, 0x10000); - } - - break; - - case 0x3b1: - genius->genius_charh = val; - break; - - /* Emulated CRTC, register select */ - case 0x3b2: case 0x3b4: case 0x3b6: - case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - genius->mda_crtcreg = val & 31; - break; - - /* Emulated CRTC, value */ - case 0x3b3: case 0x3b5: case 0x3b7: - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - genius->mda_crtc[genius->mda_crtcreg] = val; - genius_recalctimings(genius); - return; - - /* Emulated MDA control register */ - case 0x3b8: - genius->mda_ctrl = val; - return; - /* Emulated CGA control register */ - case 0x3D8: - genius->cga_ctrl = val; - return; - /* Emulated CGA colour register */ - case 0x3D9: - genius->cga_colour = val; - return; - } -} - -uint8_t genius_in(uint16_t addr, void *p) -{ - genius_t *genius = (genius_t *)p; - - switch (addr) - { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - return genius->mda_crtcreg; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - return genius->mda_crtc[genius->mda_crtcreg]; - case 0x3b8: - return genius->mda_ctrl; - case 0x3d9: - return genius->cga_colour; - case 0x3ba: - return genius->mda_stat; - case 0x3d8: - return genius->cga_ctrl; - case 0x3da: - return genius->cga_stat; - } - return 0xff; -} - -void genius_write(uint32_t addr, uint8_t val, void *p) -{ - genius_t *genius = (genius_t *)p; - egawrites++; - - if (genius->genius_control & 1) - { - addr = addr % 0x28000; - } - else - /* If hi-res memory is disabled, only visible in the B000 segment */ - { - addr = (addr & 0xFFFF) + 0x10000; - } - genius->vram[addr] = val; -} - - - -uint8_t genius_read(uint32_t addr, void *p) -{ - genius_t *genius = (genius_t *)p; - egareads++; - - if (genius->genius_control & 1) - { - addr = addr % 0x28000; - } - else - /* If hi-res memory is disabled, only visible in the B000 segment */ - { - addr = (addr & 0xFFFF) + 0x10000; - } - return genius->vram[addr]; -} - -void genius_recalctimings(genius_t *genius) -{ - double disptime; - double _dispontime, _dispofftime; - - disptime = 0x31; - _dispontime = 0x28; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - genius->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - genius->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); -} - - -/* Draw a single line of the screen in either text mode */ -void genius_textline(genius_t *genius, uint8_t background) -{ - int x; - int w = 80; /* 80 characters across */ - int cw = 9; /* Each character is 9 pixels wide */ - uint8_t chr, attr; - uint8_t bitmap[2]; - int blink, c, row; - int drawcursor, cursorline; - uint16_t addr; - uint8_t sc; - int charh; - uint16_t ma = (genius->mda_crtc[13] | (genius->mda_crtc[12] << 8)) & 0x3fff; - uint16_t ca = (genius->mda_crtc[15] | (genius->mda_crtc[14] << 8)) & 0x3fff; - unsigned char *framebuf = genius->vram + 0x10000; - uint32_t col; - - /* Character height is 12-15 */ - charh = 15 - (genius->genius_charh & 3); - if (genius->genius_charh & 0x10) - { - row = ((genius->displine >> 1) / charh); - sc = ((genius->displine >> 1) % charh); - } - else - { - row = (genius->displine / charh); - sc = (genius->displine % charh); - } - addr = ((ma & ~1) + row * w) * 2; - - ma += (row * w); - - if ((genius->mda_crtc[10] & 0x60) == 0x20) - { - cursorline = 0; - } - else - { - cursorline = ((genius->mda_crtc[10] & 0x1F) <= sc) && - ((genius->mda_crtc[11] & 0x1F) >= sc); - } - - for (x = 0; x < w; x++) - { - chr = framebuf[(addr + 2 * x) & 0x3FFF]; - attr = framebuf[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && genius->enabled && - (genius->mda_ctrl & 8)); - - switch (genius->mda_crtc[10] & 0x60) - { - case 0x00: drawcursor = drawcursor && (genius->blink & 16); break; - case 0x60: drawcursor = drawcursor && (genius->blink & 32); break; - } - blink = ((genius->blink & 16) && - (genius->mda_ctrl & 0x20) && - (attr & 0x80) && !drawcursor); - - if (genius->mda_ctrl & 0x20) attr &= 0x7F; - /* MDA underline */ - if (sc == charh && ((attr & 7) == 1)) - { - col = mdacols[attr][blink][1]; - - if (genius->genius_control & 0x20) - { - col ^= 0xffffff; - } - - for (c = 0; c < cw; c++) - { - if (col != background) - ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + c] = col; - } - } - else /* Draw 8 pixels of character */ - { - bitmap[0] = fontdat8x12[chr][sc]; - for (c = 0; c < 8; c++) - { - col = mdacols[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; - if (!(genius->enabled) || !(genius->mda_ctrl & 8)) - col = mdacols[0][0][0]; - - if (genius->genius_control & 0x20) - { - col ^= 0xffffff; - } - if (col != background) - { - ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + c] = col; - } - } - /* The ninth pixel column... */ - if ((chr & ~0x1f) == 0xc0) - { - /* Echo column 8 for the graphics chars */ - col = ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + 7]; - if (col != background) - ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + 8] = col; - } - else /* Otherwise fill with background */ - { - col = mdacols[attr][blink][0]; - if (genius->genius_control & 0x20) - { - col ^= 0xffffff; - } - if (col != background) - ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + 8] = col; - } - if (drawcursor) - { - for (c = 0; c < cw; c++) - ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + c] ^= mdacols[attr][0][1]; - } - ++ma; - } - } -} - -/* Draw a line in the CGA 640x200 mode */ -void genius_cgaline(genius_t *genius) -{ - int x, c; - uint32_t dat; - uint32_t ink; - uint32_t addr; - - ink = (genius->genius_control & 0x20) ? genius_pal[0] : genius_pal[3]; - /* We draw the CGA at row 600 */ - if (genius->displine < 600) - { - return; - } - addr = 0x18000 + 80 * ((genius->displine - 600) >> 2); - if ((genius->displine - 600) & 2) - { - addr += 0x2000; - } - - for (x = 0; x < 80; x++) - { - dat = genius->vram[addr]; - addr++; - - for (c = 0; c < 8; c++) - { - if (dat & 0x80) - { - ((uint32_t *)buffer32->line[genius->displine])[x*8 + c] = ink; - } - dat = dat << 1; - } - } -} - -/* Draw a line in the native high-resolution mode */ -void genius_hiresline(genius_t *genius) -{ - int x, c; - uint32_t dat; - uint32_t ink; - uint32_t addr; - - ink = (genius->genius_control & 0x20) ? genius_pal[0] : genius_pal[3]; - /* The first 512 lines live at A0000 */ - if (genius->displine < 512) - { - addr = 128 * genius->displine; - } - else /* The second 496 live at B8000 */ - { - addr = 0x18000 + 128 * (genius->displine - 512); - } - - for (x = 0; x < 91; x++) - { - dat = genius->vram[addr]; - addr++; - - for (c = 0; c < 8; c++) - { - if (dat & 0x80) - { - ((uint32_t *)buffer32->line[genius->displine])[x*8 + c] = ink; - } - dat = dat << 1; - } - } -} - -void genius_poll(void *p) -{ - genius_t *genius = (genius_t *)p; - int x; - uint8_t background; - - if (!genius->linepos) - { - genius->vidtime += genius->dispofftime; - genius->cga_stat |= 1; - genius->mda_stat |= 1; - genius->linepos = 1; - if (genius->dispon) - { - if (genius->genius_control & 0x20) - { - background = genius_pal[3]; - } - else - { - background = genius_pal[0]; - } - if (genius->displine == 0) - { - video_wait_for_buffer(); - } - /* Start off with a blank line */ - for (x = 0; x < GENIUS_XSIZE; x++) - { - ((uint32_t *)buffer32->line[genius->displine])[x] = background; - } - /* If graphics display enabled, draw graphics on top - * of the blanked line */ - if (genius->cga_ctrl & 8) - { - if (genius->genius_control & 8) - { - genius_cgaline(genius); - } - else - { - genius_hiresline(genius); - } - } - /* If MDA display is enabled, draw MDA text on top - * of the lot */ - if (genius->mda_ctrl & 8) - { - genius_textline(genius, background); - } - } - genius->displine++; - /* Hardcode a fixed refresh rate and VSYNC timing */ - if (genius->displine == 1008) /* Start of VSYNC */ - { - genius->cga_stat |= 8; - genius->dispon = 0; - } - if (genius->displine == 1040) /* End of VSYNC */ - { - genius->displine = 0; - genius->cga_stat &= ~8; - genius->dispon = 1; - } - } - else - { - if (genius->dispon) - { - genius->cga_stat &= ~1; - genius->mda_stat &= ~1; - } - genius->vidtime += genius->dispontime; - genius->linepos = 0; - - if (genius->displine == 1008) - { -/* Hardcode GENIUS_XSIZE * GENIUS_YSIZE window size */ - if (GENIUS_XSIZE != xsize || GENIUS_YSIZE != ysize) - { - xsize = GENIUS_XSIZE; - ysize = GENIUS_YSIZE; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); - - frames++; - /* Fixed 728x1008 resolution */ - video_res_x = GENIUS_XSIZE; - video_res_y = GENIUS_YSIZE; - video_bpp = 1; - genius->blink++; - } - } -} - -void *genius_init(const device_t *info) -{ - int c; - genius_t *genius = malloc(sizeof(genius_t)); - memset(genius, 0, sizeof(genius_t)); - - /* 160k video RAM */ - genius->vram = malloc(0x28000); - - loadfont(BIOS_ROM_PATH, 4); - - timer_add(genius_poll, &genius->vidtime, TIMER_ALWAYS_ENABLED, genius); - - /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in - * high-resolution modes) */ - mem_mapping_add(&genius->mapping, 0xb0000, 0x10000, genius_read, NULL, NULL, genius_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, genius); - /* Respond to both MDA and CGA I/O ports */ - io_sethandler(0x03b0, 0x000C, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); - io_sethandler(0x03d0, 0x0010, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); - - genius_pal[0] = makecol(0x00, 0x00, 0x00); - genius_pal[1] = makecol(0x55, 0x55, 0x55); - genius_pal[2] = makecol(0xaa, 0xaa, 0xaa); - genius_pal[3] = makecol(0xff, 0xff, 0xff); - - /* MDA attributes */ - /* I don't know if the Genius's MDA emulation actually does - * emulate bright / non-bright. For the time being pretend it does. */ - for (c = 0; c < 256; c++) - { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = genius_pal[0]; - if (c & 8) mdacols[c][0][1] = genius_pal[3]; - else mdacols[c][0][1] = genius_pal[2]; - } - mdacols[0x70][0][1] = genius_pal[0]; - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = genius_pal[3]; - mdacols[0xF0][0][1] = genius_pal[0]; - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = genius_pal[3]; - mdacols[0x78][0][1] = genius_pal[2]; - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = genius_pal[3]; - mdacols[0xF8][0][1] = genius_pal[2]; - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = genius_pal[3]; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = genius_pal[0]; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = genius_pal[0]; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = genius_pal[0]; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = genius_pal[0]; - -/* Start off in 80x25 text mode */ - genius->cga_stat = 0xF4; - genius->genius_mode = 2; - genius->enabled = 1; - genius->genius_charh = 0x90; /* Native character height register */ - return genius; -} - -void genius_close(void *p) -{ - genius_t *genius = (genius_t *)p; - - free(genius->vram); - free(genius); -} - -static int genius_available() -{ - return rom_present(BIOS_ROM_PATH); -} - -void genius_speed_changed(void *p) -{ - genius_t *genius = (genius_t *)p; - - genius_recalctimings(genius); -} - -const device_t genius_device = -{ - "Genius VHR", - DEVICE_ISA, 0, - genius_init, genius_close, NULL, - genius_available, - genius_speed_changed, - NULL, - NULL -}; diff --git a/backup code/video - Cópia/vid_genius.h b/backup code/video - Cópia/vid_genius.h deleted file mode 100644 index e1388ec5c..000000000 --- a/backup code/video - Cópia/vid_genius.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t genius_device; diff --git a/backup code/video - Cópia/vid_hercules.c b/backup code/video - Cópia/vid_hercules.c deleted file mode 100644 index 0724fb433..000000000 --- a/backup code/video - Cópia/vid_hercules.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * 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. - * - * Hercules emulation. - * - * Version: @(#)vid_hercules.c 1.0.11 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "../rom.h" -#include "../io.h" -#include "../lpt.h" -#include "../pit.h" -#include "../timer.h" -#include "../device.h" -#include "video.h" -#include "vid_hercules.h" - - -typedef struct hercules_t -{ - mem_mapping_t mapping; - - uint8_t crtc[32]; - int crtcreg; - - uint8_t ctrl, ctrl2, stat; - - int64_t dispontime, dispofftime; - int64_t vidtime; - - int firstline, lastline; - - int linepos, displine; - int vc, sc; - uint16_t ma, maback; - int con, coff, cursoron; - int dispon, blink; - int64_t vsynctime; - int vadj; - - uint8_t *vram; -} hercules_t; - -static int mdacols[256][2][2]; - -void hercules_recalctimings(hercules_t *hercules); -void hercules_write(uint32_t addr, uint8_t val, void *p); -uint8_t hercules_read(uint32_t addr, void *p); - - -void hercules_out(uint16_t addr, uint8_t val, void *p) -{ - hercules_t *hercules = (hercules_t *)p; - switch (addr) - { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - hercules->crtcreg = val & 31; - return; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - hercules->crtc[hercules->crtcreg] = val; - if (hercules->crtc[10] == 6 && hercules->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ - { - hercules->crtc[10] = 0xb; - hercules->crtc[11] = 0xc; - } - hercules_recalctimings(hercules); - return; - case 0x3b8: - hercules->ctrl = val; - return; - case 0x3bf: - hercules->ctrl2 = val; - if (val & 2) - mem_mapping_set_addr(&hercules->mapping, 0xb0000, 0x10000); - else - mem_mapping_set_addr(&hercules->mapping, 0xb0000, 0x08000); - return; - } -} - -uint8_t hercules_in(uint16_t addr, void *p) -{ - hercules_t *hercules = (hercules_t *)p; - switch (addr) - { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - return hercules->crtcreg; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - return hercules->crtc[hercules->crtcreg]; - case 0x3ba: - return (hercules->stat & 0xf) | ((hercules->stat & 8) << 4); - } - return 0xff; -} - -void hercules_write(uint32_t addr, uint8_t val, void *p) -{ - hercules_t *hercules = (hercules_t *)p; - egawrites++; - hercules->vram[addr & 0xffff] = val; -} - -uint8_t hercules_read(uint32_t addr, void *p) -{ - hercules_t *hercules = (hercules_t *)p; - egareads++; - return hercules->vram[addr & 0xffff]; -} - -void hercules_recalctimings(hercules_t *hercules) -{ - double disptime; - double _dispontime, _dispofftime; - disptime = hercules->crtc[0] + 1; - _dispontime = hercules->crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - hercules->dispontime = (int64_t)(_dispontime * (1 << TIMER_SHIFT)); - hercules->dispofftime = (int64_t)(_dispofftime * (1 << TIMER_SHIFT)); -} - -void hercules_poll(void *p) -{ - hercules_t *hercules = (hercules_t *)p; - uint16_t ca = (hercules->crtc[15] | (hercules->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - uint16_t dat; - int oldsc; - int blink; - if (!hercules->linepos) - { - hercules->vidtime += hercules->dispofftime; - hercules->stat |= 1; - hercules->linepos = 1; - oldsc = hercules->sc; - if ((hercules->crtc[8] & 3) == 3) - hercules->sc = (hercules->sc << 1) & 7; - if (hercules->dispon) - { - if (hercules->displine < hercules->firstline) - { - hercules->firstline = hercules->displine; - video_wait_for_buffer(); - } - hercules->lastline = hercules->displine; - if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) - { - ca = (hercules->sc & 3) * 0x2000; - if ((hercules->ctrl & 0x80) && (hercules->ctrl2 & 2)) - ca += 0x8000; -// printf("Draw herc %04X\n",ca); - for (x = 0; x < hercules->crtc[1]; x++) - { - dat = (hercules->vram[((hercules->ma << 1) & 0x1fff) + ca] << 8) | hercules->vram[((hercules->ma << 1) & 0x1fff) + ca + 1]; - hercules->ma++; - for (c = 0; c < 16; c++) - buffer->line[hercules->displine][(x << 4) + c] = (dat & (32768 >> c)) ? 7 : 0; - } - } - else - { - for (x = 0; x < hercules->crtc[1]; x++) - { - chr = hercules->vram[(hercules->ma << 1) & 0xfff]; - attr = hercules->vram[((hercules->ma << 1) + 1) & 0xfff]; - drawcursor = ((hercules->ma == ca) && hercules->con && hercules->cursoron); - blink = ((hercules->blink & 16) && (hercules->ctrl & 0x20) && (attr & 0x80) && !drawcursor); - if (hercules->sc == 12 && ((attr & 7) == 1)) - { - for (c = 0; c < 9; c++) - buffer->line[hercules->displine][(x * 9) + c] = mdacols[attr][blink][1]; - } - else - { - for (c = 0; c < 8; c++) - buffer->line[hercules->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][hercules->sc] & (1 << (c ^ 7))) ? 1 : 0]; - if ((chr & ~0x1f) == 0xc0) buffer->line[hercules->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][hercules->sc] & 1]; - else buffer->line[hercules->displine][(x * 9) + 8] = mdacols[attr][blink][0]; - } - hercules->ma++; - if (drawcursor) - { - for (c = 0; c < 9; c++) - buffer->line[hercules->displine][(x * 9) + c] ^= mdacols[attr][0][1]; - } - } - } - } - hercules->sc = oldsc; - if (hercules->vc == hercules->crtc[7] && !hercules->sc) - { - hercules->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); - } - hercules->displine++; - if (hercules->displine >= 500) - hercules->displine = 0; - } - else - { - hercules->vidtime += hercules->dispontime; - if (hercules->dispon) - hercules->stat &= ~1; - hercules->linepos = 0; - if (hercules->vsynctime) - { - hercules->vsynctime--; - if (!hercules->vsynctime) - { - hercules->stat &= ~8; -// printf("VSYNC off %i %i\n",vc,sc); - } - } - if (hercules->sc == (hercules->crtc[11] & 31) || ((hercules->crtc[8] & 3) == 3 && hercules->sc == ((hercules->crtc[11] & 31) >> 1))) - { - hercules->con = 0; - hercules->coff = 1; - } - if (hercules->vadj) - { - hercules->sc++; - hercules->sc &= 31; - hercules->ma = hercules->maback; - hercules->vadj--; - if (!hercules->vadj) - { - hercules->dispon = 1; - hercules->ma = hercules->maback = (hercules->crtc[13] | (hercules->crtc[12] << 8)) & 0x3fff; - hercules->sc = 0; - } - } - else if (hercules->sc == hercules->crtc[9] || ((hercules->crtc[8] & 3) == 3 && hercules->sc == (hercules->crtc[9] >> 1))) - { - hercules->maback = hercules->ma; - hercules->sc = 0; - oldvc = hercules->vc; - hercules->vc++; - hercules->vc &= 127; - if (hercules->vc == hercules->crtc[6]) - hercules->dispon = 0; - if (oldvc == hercules->crtc[4]) - { -// printf("Display over at %i\n",displine); - hercules->vc = 0; - hercules->vadj = hercules->crtc[5]; - if (!hercules->vadj) hercules->dispon=1; - if (!hercules->vadj) hercules->ma = hercules->maback = (hercules->crtc[13] | (hercules->crtc[12] << 8)) & 0x3fff; - if ((hercules->crtc[10] & 0x60) == 0x20) hercules->cursoron = 0; - else hercules->cursoron = hercules->blink & 16; - } - if (hercules->vc == hercules->crtc[7]) - { - hercules->dispon = 0; - hercules->displine = 0; - hercules->vsynctime = 16;//(crtcm[3]>>4)+1; - if (hercules->crtc[7]) - { -// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline); - if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) x = hercules->crtc[1] << 4; - else x = hercules->crtc[1] * 9; - hercules->lastline++; - if ((x != xsize) || ((hercules->lastline - hercules->firstline) != ysize) || video_force_resize_get()) - { - xsize = x; - ysize = hercules->lastline - hercules->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]); - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen_8(0, hercules->firstline, 0, ysize, xsize, ysize); - frames++; - if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) - { - video_res_x = hercules->crtc[1] * 16; - video_res_y = hercules->crtc[6] * 4; - video_bpp = 1; - } - else - { - video_res_x = hercules->crtc[1]; - video_res_y = hercules->crtc[6]; - video_bpp = 0; - } - } - hercules->firstline = 1000; - hercules->lastline = 0; - hercules->blink++; - } - } - else - { - hercules->sc++; - hercules->sc &= 31; - hercules->ma = hercules->maback; - } - if ((hercules->sc == (hercules->crtc[10] & 31) || ((hercules->crtc[8] & 3) == 3 && hercules->sc == ((hercules->crtc[10] & 31) >> 1)))) - { - hercules->con = 1; -// printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); - } - } -} - - -void *hercules_init(const device_t *info) -{ - int c; - hercules_t *hercules = malloc(sizeof(hercules_t)); - memset(hercules, 0, sizeof(hercules_t)); - - hercules->vram = malloc(0x10000); - - timer_add(hercules_poll, &hercules->vidtime, TIMER_ALWAYS_ENABLED, hercules); - mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, hercules); - io_sethandler(0x03b0, 0x0010, hercules_in, NULL, NULL, hercules_out, NULL, NULL, hercules); - - for (c = 0; c < 256; c++) - { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; - if (c & 8) mdacols[c][0][1] = 15 + 16; - else mdacols[c][0][1] = 7 + 16; - } - mdacols[0x70][0][1] = 16; - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15; - mdacols[0xF0][0][1] = 16; - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15; - mdacols[0x78][0][1] = 16 + 7; - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15; - mdacols[0xF8][0][1] = 16 + 7; - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; - - overscan_x = overscan_y = 0; - - cga_palette = device_get_config_int("rgb_type") << 1; - if (cga_palette > 6) - { - cga_palette = 0; - } - cgapal_rebuild(); - - lpt3_init(0x3BC); - - return hercules; -} - -void hercules_close(void *p) -{ - hercules_t *hercules = (hercules_t *)p; - - free(hercules->vram); - free(hercules); -} - -void hercules_speed_changed(void *p) -{ - hercules_t *hercules = (hercules_t *)p; - - hercules_recalctimings(hercules); -} - -static const device_config_t hercules_config[] = -{ - { - "rgb_type", "Display type", CONFIG_SELECTION, "", 0, - { - { - "Default", 0 - }, - { - "Green", 1 - }, - { - "Amber", 2 - }, - { - "Gray", 3 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t hercules_device = -{ - "Hercules", - DEVICE_ISA, 0, - hercules_init, hercules_close, NULL, - NULL, - hercules_speed_changed, - NULL, - hercules_config -}; diff --git a/backup code/video - Cópia/vid_hercules.h b/backup code/video - Cópia/vid_hercules.h deleted file mode 100644 index 3c145e18f..000000000 --- a/backup code/video - Cópia/vid_hercules.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t hercules_device; diff --git a/backup code/video - Cópia/vid_herculesplus.c b/backup code/video - Cópia/vid_herculesplus.c deleted file mode 100644 index 1bf4118fc..000000000 --- a/backup code/video - Cópia/vid_herculesplus.c +++ /dev/null @@ -1,739 +0,0 @@ -/* - * 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. - * - * Hercules InColor emulation. - * - * Version: @(#)vid_herculesplus.c 1.0.9 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../lpt.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "video.h" -#include "vid_herculesplus.h" - - -/* extended CRTC registers */ - -#define HERCULESPLUS_CRTC_XMODE 20 /* xMode register */ -#define HERCULESPLUS_CRTC_UNDER 21 /* Underline */ -#define HERCULESPLUS_CRTC_OVER 22 /* Overstrike */ - -/* character width */ -#define HERCULESPLUS_CW ((herculesplus->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL) ? 8 : 9) - -/* mode control register */ -#define HERCULESPLUS_CTRL_GRAPH 0x02 -#define HERCULESPLUS_CTRL_ENABLE 0x08 -#define HERCULESPLUS_CTRL_BLINK 0x20 -#define HERCULESPLUS_CTRL_PAGE1 0x80 - -/* CRTC status register */ -#define HERCULESPLUS_STATUS_HSYNC 0x01 /* horizontal sync */ -#define HERCULESPLUS_STATUS_LIGHT 0x02 -#define HERCULESPLUS_STATUS_VIDEO 0x08 -#define HERCULESPLUS_STATUS_ID 0x10 /* Card identification */ -#define HERCULESPLUS_STATUS_VSYNC 0x80 /* -vertical sync */ - -/* configuration switch register */ -#define HERCULESPLUS_CTRL2_GRAPH 0x01 -#define HERCULESPLUS_CTRL2_PAGE1 0x02 - -/* extended mode register */ -#define HERCULESPLUS_XMODE_RAMFONT 0x01 -#define HERCULESPLUS_XMODE_90COL 0x02 - -typedef struct herculesplus_t -{ - mem_mapping_t mapping; - - uint8_t crtc[32]; - int crtcreg; - - uint8_t ctrl, ctrl2, stat; - - int64_t dispontime, dispofftime; - int64_t vidtime; - - int firstline, lastline; - - int linepos, displine; - int vc, sc; - uint16_t ma, maback; - int con, coff, cursoron; - int dispon, blink; - int64_t vsynctime; - int vadj; - - uint8_t *vram; -} herculesplus_t; - -void herculesplus_recalctimings(herculesplus_t *herculesplus); -void herculesplus_write(uint32_t addr, uint8_t val, void *p); -uint8_t herculesplus_read(uint32_t addr, void *p); - -static int mdacols[256][2][2]; - -void herculesplus_out(uint16_t addr, uint8_t val, void *p) -{ - herculesplus_t *herculesplus = (herculesplus_t *)p; - switch (addr) - { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - herculesplus->crtcreg = val & 31; - return; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - if (herculesplus->crtcreg > 22) return; - herculesplus->crtc[herculesplus->crtcreg] = val; - if (herculesplus->crtc[10] == 6 && herculesplus->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ - { - herculesplus->crtc[10] = 0xb; - herculesplus->crtc[11] = 0xc; - } - herculesplus_recalctimings(herculesplus); - return; - case 0x3b8: - herculesplus->ctrl = val; - return; - case 0x3bf: - herculesplus->ctrl2 = val; - if (val & 2) - mem_mapping_set_addr(&herculesplus->mapping, 0xb0000, 0x10000); - else - mem_mapping_set_addr(&herculesplus->mapping, 0xb0000, 0x08000); - return; - } -} - -uint8_t herculesplus_in(uint16_t addr, void *p) -{ - herculesplus_t *herculesplus = (herculesplus_t *)p; - switch (addr) - { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - return herculesplus->crtcreg; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - if (herculesplus->crtcreg > 22) return 0xff; - return herculesplus->crtc[herculesplus->crtcreg]; - case 0x3ba: - /* 0x50: InColor card identity */ - return (herculesplus->stat & 0xf) | ((herculesplus->stat & 8) << 4) | 0x10; - } - return 0xff; -} - -void herculesplus_write(uint32_t addr, uint8_t val, void *p) -{ - herculesplus_t *herculesplus = (herculesplus_t *)p; - - egawrites++; - - addr &= 0xFFFF; - - herculesplus->vram[addr] = val; -} - -uint8_t herculesplus_read(uint32_t addr, void *p) -{ - herculesplus_t *herculesplus = (herculesplus_t *)p; - - egareads++; - - addr &= 0xFFFF; - return herculesplus->vram[addr]; -} - - - -void herculesplus_recalctimings(herculesplus_t *herculesplus) -{ - double disptime; - double _dispontime, _dispofftime; - disptime = herculesplus->crtc[0] + 1; - _dispontime = herculesplus->crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - herculesplus->dispontime = (int64_t)(_dispontime * (1 << TIMER_SHIFT)); - herculesplus->dispofftime = (int64_t)(_dispofftime * (1 << TIMER_SHIFT)); -} - - -static void herculesplus_draw_char_rom(herculesplus_t *herculesplus, int x, uint8_t chr, uint8_t attr) -{ - unsigned i; - int elg, blk; - unsigned ull; - unsigned val; - unsigned ifg, ibg; - const unsigned char *fnt; - int cw = HERCULESPLUS_CW; - - blk = 0; - if (herculesplus->ctrl & HERCULESPLUS_CTRL_BLINK) - { - if (attr & 0x80) - { - blk = (herculesplus->blink & 16); - } - attr &= 0x7f; - } - - /* MDA-compatible attributes */ - ibg = 0; - ifg = 7; - if ((attr & 0x77) == 0x70) /* Invert */ - { - ifg = 0; - ibg = 7; - } - if (attr & 8) - { - ifg |= 8; /* High intensity FG */ - } - if (attr & 0x80) - { - ibg |= 8; /* High intensity BG */ - } - if ((attr & 0x77) == 0) /* Blank */ - { - ifg = ibg; - } - ull = ((attr & 0x07) == 1) ? 13 : 0xffff; - - if (herculesplus->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL) - { - elg = 0; - } - else - { - elg = ((chr >= 0xc0) && (chr <= 0xdf)); - } - - fnt = &(fontdatm[chr][herculesplus->sc]); - - if (blk) - { - val = 0x000; /* Blinking, draw all background */ - } - else if (herculesplus->sc == ull) - { - val = 0x1ff; /* Underscore, draw all foreground */ - } - else - { - val = fnt[0] << 1; - - if (elg) - { - val |= (val >> 1) & 1; - } - } - for (i = 0; i < cw; i++) - { - buffer->line[herculesplus->displine][x * cw + i] = (val & 0x100) ? ifg : ibg; - val = val << 1; - } -} - - -static void herculesplus_draw_char_ram4(herculesplus_t *herculesplus, int x, uint8_t chr, uint8_t attr) -{ - unsigned i; - int elg, blk; - unsigned ull; - unsigned val; - unsigned ifg, ibg, cfg; - const unsigned char *fnt; - int cw = HERCULESPLUS_CW; - int blink = herculesplus->ctrl & HERCULESPLUS_CTRL_BLINK; - - blk = 0; - if (blink) - { - if (attr & 0x80) - { - blk = (herculesplus->blink & 16); - } - attr &= 0x7f; - } - - /* MDA-compatible attributes */ - ibg = 0; - ifg = 7; - if ((attr & 0x77) == 0x70) /* Invert */ - { - ifg = 0; - ibg = 7; - } - if (attr & 8) - { - ifg |= 8; /* High intensity FG */ - } - if (attr & 0x80) - { - ibg |= 8; /* High intensity BG */ - } - if ((attr & 0x77) == 0) /* Blank */ - { - ifg = ibg; - } - ull = ((attr & 0x07) == 1) ? 13 : 0xffff; - if (herculesplus->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL) - { - elg = 0; - } - else - { - elg = ((chr >= 0xc0) && (chr <= 0xdf)); - } - fnt = herculesplus->vram + 0x4000 + 16 * chr + herculesplus->sc; - - if (blk) - { - /* Blinking, draw all background */ - val = 0x000; - } - else if (herculesplus->sc == ull) - { - /* Underscore, draw all foreground */ - val = 0x1ff; - } - else - { - val = fnt[0x00000] << 1; - - if (elg) - { - val |= (val >> 1) & 1; - } - } - for (i = 0; i < cw; i++) - { - /* Generate pixel colour */ - cfg = 0; - /* cfg = colour of foreground pixels */ - if ((attr & 0x77) == 0) cfg = ibg; /* 'blank' attribute */ - - buffer->line[herculesplus->displine][x * cw + i] = mdacols[attr][blink][cfg]; - val = val << 1; - } -} - - -static void herculesplus_draw_char_ram48(herculesplus_t *herculesplus, int x, uint8_t chr, uint8_t attr) -{ - unsigned i; - int elg, blk, ul, ol, bld; - unsigned ull, oll, ulc = 0, olc = 0; - unsigned val; - unsigned ibg, cfg; - const unsigned char *fnt; - int cw = HERCULESPLUS_CW; - int blink = herculesplus->ctrl & HERCULESPLUS_CTRL_BLINK; - int font = (attr & 0x0F); - - if (font >= 12) font &= 7; - - blk = 0; - if (blink) - { - if (attr & 0x40) - { - blk = (herculesplus->blink & 16); - } - attr &= 0x7f; - } - /* MDA-compatible attributes */ - if (blink) - { - ibg = (attr & 0x80) ? 8 : 0; - bld = 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; - } - else - { - bld = (attr & 0x80) ? 1 : 0; - ibg = (attr & 0x40) ? 0x0F : 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; - } - if (ul) - { - ull = herculesplus->crtc[HERCULESPLUS_CRTC_UNDER] & 0x0F; - ulc = (herculesplus->crtc[HERCULESPLUS_CRTC_UNDER] >> 4) & 0x0F; - if (ulc == 0) ulc = 7; - } - else - { - ull = 0xFFFF; - } - if (ol) - { - oll = herculesplus->crtc[HERCULESPLUS_CRTC_OVER] & 0x0F; - olc = (herculesplus->crtc[HERCULESPLUS_CRTC_OVER] >> 4) & 0x0F; - if (olc == 0) olc = 7; - } - else - { - oll = 0xFFFF; - } - - if (herculesplus->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL) - { - elg = 0; - } - else - { - elg = ((chr >= 0xc0) && (chr <= 0xdf)); - } - fnt = herculesplus->vram + 0x4000 + 16 * chr + 4096 * font + herculesplus->sc; - - if (blk) - { - /* Blinking, draw all background */ - val = 0x000; - } - else if (herculesplus->sc == ull) - { - /* Underscore, draw all foreground */ - val = 0x1ff; - } - else - { - val = fnt[0x00000] << 1; - - if (elg) - { - val |= (val >> 1) & 1; - } - if (bld) - { - val |= (val >> 1); - } - } - for (i = 0; i < cw; i++) - { - /* Generate pixel colour */ - cfg = val & 0x100; - if (herculesplus->sc == oll) - { - cfg = olc ^ ibg; /* Strikethrough */ - } - else if (herculesplus->sc == ull) - { - cfg = ulc ^ ibg; /* Underline */ - } - else - { - cfg |= ibg; - } - - buffer->line[herculesplus->displine][(x * cw) + i] = mdacols[attr][blink][cfg]; - val = val << 1; - } -} - -static void herculesplus_text_line(herculesplus_t *herculesplus, uint16_t ca) -{ - int drawcursor; - int x, c; - uint8_t chr, attr; - uint32_t col; - - for (x = 0; x < herculesplus->crtc[1]; x++) - { - chr = herculesplus->vram[(herculesplus->ma << 1) & 0xfff]; - attr = herculesplus->vram[((herculesplus->ma << 1) + 1) & 0xfff]; - - drawcursor = ((herculesplus->ma == ca) && herculesplus->con && herculesplus->cursoron); - - switch (herculesplus->crtc[HERCULESPLUS_CRTC_XMODE] & 5) - { - case 0: - case 4: /* ROM font */ - herculesplus_draw_char_rom(herculesplus, x, chr, attr); - break; - case 1: /* 4k RAMfont */ - herculesplus_draw_char_ram4(herculesplus, x, chr, attr); - break; - case 5: /* 48k RAMfont */ - herculesplus_draw_char_ram48(herculesplus, x, chr, attr); - break; - - } - ++herculesplus->ma; - if (drawcursor) - { - int cw = HERCULESPLUS_CW; - - col = mdacols[attr][0][1]; - for (c = 0; c < cw; c++) - { - ((uint32_t *)buffer32->line[herculesplus->displine])[x * cw + c] = col; - } - } - } -} - - -static void herculesplus_graphics_line(herculesplus_t *herculesplus) -{ - uint16_t ca; - int x, c, plane = 0; - uint16_t val; - - /* Graphics mode. */ - ca = (herculesplus->sc & 3) * 0x2000; - if ((herculesplus->ctrl & HERCULESPLUS_CTRL_PAGE1) && (herculesplus->ctrl2 & HERCULESPLUS_CTRL2_PAGE1)) - ca += 0x8000; - - for (x = 0; x < herculesplus->crtc[1]; x++) - { - val = (herculesplus->vram[((herculesplus->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) - | herculesplus->vram[((herculesplus->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; - - herculesplus->ma++; - for (c = 0; c < 16; c++) - { - val >>= 1; - - ((uint32_t *)buffer32->line[herculesplus->displine])[(x << 4) + c] = (val & 1) ? 7 : 0; - } - } -} - -void herculesplus_poll(void *p) -{ - herculesplus_t *herculesplus = (herculesplus_t *)p; - uint16_t ca = (herculesplus->crtc[15] | (herculesplus->crtc[14] << 8)) & 0x3fff; - int x; - int oldvc; - int oldsc; - - if (!herculesplus->linepos) - { - herculesplus->vidtime += herculesplus->dispofftime; - herculesplus->stat |= 1; - herculesplus->linepos = 1; - oldsc = herculesplus->sc; - if ((herculesplus->crtc[8] & 3) == 3) - herculesplus->sc = (herculesplus->sc << 1) & 7; - if (herculesplus->dispon) - { - if (herculesplus->displine < herculesplus->firstline) - { - herculesplus->firstline = herculesplus->displine; - video_wait_for_buffer(); - } - herculesplus->lastline = herculesplus->displine; - if ((herculesplus->ctrl & HERCULESPLUS_CTRL_GRAPH) && (herculesplus->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) - { - herculesplus_graphics_line(herculesplus); - } - else - { - herculesplus_text_line(herculesplus, ca); - } - } - herculesplus->sc = oldsc; - if (herculesplus->vc == herculesplus->crtc[7] && !herculesplus->sc) - { - herculesplus->stat |= 8; - } - herculesplus->displine++; - if (herculesplus->displine >= 500) - herculesplus->displine = 0; - } - else - { - herculesplus->vidtime += herculesplus->dispontime; - if (herculesplus->dispon) - herculesplus->stat &= ~1; - herculesplus->linepos = 0; - if (herculesplus->vsynctime) - { - herculesplus->vsynctime--; - if (!herculesplus->vsynctime) - { - herculesplus->stat &= ~8; - } - } - if (herculesplus->sc == (herculesplus->crtc[11] & 31) || ((herculesplus->crtc[8] & 3) == 3 && herculesplus->sc == ((herculesplus->crtc[11] & 31) >> 1))) - { - herculesplus->con = 0; - herculesplus->coff = 1; - } - if (herculesplus->vadj) - { - herculesplus->sc++; - herculesplus->sc &= 31; - herculesplus->ma = herculesplus->maback; - herculesplus->vadj--; - if (!herculesplus->vadj) - { - herculesplus->dispon = 1; - herculesplus->ma = herculesplus->maback = (herculesplus->crtc[13] | (herculesplus->crtc[12] << 8)) & 0x3fff; - herculesplus->sc = 0; - } - } - else if (herculesplus->sc == herculesplus->crtc[9] || ((herculesplus->crtc[8] & 3) == 3 && herculesplus->sc == (herculesplus->crtc[9] >> 1))) - { - herculesplus->maback = herculesplus->ma; - herculesplus->sc = 0; - oldvc = herculesplus->vc; - herculesplus->vc++; - herculesplus->vc &= 127; - if (herculesplus->vc == herculesplus->crtc[6]) - herculesplus->dispon = 0; - if (oldvc == herculesplus->crtc[4]) - { - herculesplus->vc = 0; - herculesplus->vadj = herculesplus->crtc[5]; - if (!herculesplus->vadj) herculesplus->dispon=1; - if (!herculesplus->vadj) herculesplus->ma = herculesplus->maback = (herculesplus->crtc[13] | (herculesplus->crtc[12] << 8)) & 0x3fff; - if ((herculesplus->crtc[10] & 0x60) == 0x20) herculesplus->cursoron = 0; - else herculesplus->cursoron = herculesplus->blink & 16; - } - if (herculesplus->vc == herculesplus->crtc[7]) - { - herculesplus->dispon = 0; - herculesplus->displine = 0; - herculesplus->vsynctime = 16; - if (herculesplus->crtc[7]) - { - if ((herculesplus->ctrl & HERCULESPLUS_CTRL_GRAPH) && (herculesplus->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) - { - x = herculesplus->crtc[1] << 4; - } - else - { - x = herculesplus->crtc[1] * 9; - } - herculesplus->lastline++; - if ((x != xsize) || ((herculesplus->lastline - herculesplus->firstline) != ysize) || video_force_resize_get()) - { - xsize = x; - ysize = herculesplus->lastline - herculesplus->firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen(0, herculesplus->firstline, 0, herculesplus->lastline - herculesplus->firstline, xsize, herculesplus->lastline - herculesplus->firstline); - frames++; - if ((herculesplus->ctrl & HERCULESPLUS_CTRL_GRAPH) && (herculesplus->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) - { - video_res_x = herculesplus->crtc[1] * 16; - video_res_y = herculesplus->crtc[6] * 4; - video_bpp = 1; - } - else - { - video_res_x = herculesplus->crtc[1]; - video_res_y = herculesplus->crtc[6]; - video_bpp = 0; - } - } - herculesplus->firstline = 1000; - herculesplus->lastline = 0; - herculesplus->blink++; - } - } - else - { - herculesplus->sc++; - herculesplus->sc &= 31; - herculesplus->ma = herculesplus->maback; - } - if ((herculesplus->sc == (herculesplus->crtc[10] & 31) || ((herculesplus->crtc[8] & 3) == 3 && herculesplus->sc == ((herculesplus->crtc[10] & 31) >> 1)))) - { - herculesplus->con = 1; - } - } -} - -void *herculesplus_init(const device_t *info) -{ - int c; - herculesplus_t *herculesplus = malloc(sizeof(herculesplus_t)); - memset(herculesplus, 0, sizeof(herculesplus_t)); - - herculesplus->vram = malloc(0x10000); /* 64k VRAM */ - - timer_add(herculesplus_poll, &herculesplus->vidtime, TIMER_ALWAYS_ENABLED, herculesplus); - mem_mapping_add(&herculesplus->mapping, 0xb0000, 0x10000, herculesplus_read, NULL, NULL, herculesplus_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, herculesplus); - io_sethandler(0x03b0, 0x0010, herculesplus_in, NULL, NULL, herculesplus_out, NULL, NULL, herculesplus); - - for (c = 0; c < 256; c++) - { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; - if (c & 8) mdacols[c][0][1] = 15 + 16; - else mdacols[c][0][1] = 7 + 16; - } - mdacols[0x70][0][1] = 16; - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15; - mdacols[0xF0][0][1] = 16; - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15; - mdacols[0x78][0][1] = 16 + 7; - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15; - mdacols[0xF8][0][1] = 16 + 7; - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; - - lpt3_init(0x3BC); - - return herculesplus; -} - -void herculesplus_close(void *p) -{ - herculesplus_t *herculesplus = (herculesplus_t *)p; - - free(herculesplus->vram); - free(herculesplus); -} - -void herculesplus_speed_changed(void *p) -{ - herculesplus_t *herculesplus = (herculesplus_t *)p; - - herculesplus_recalctimings(herculesplus); -} - -const device_t herculesplus_device = -{ - "Hercules Plus", - DEVICE_ISA, 0, - herculesplus_init, herculesplus_close, NULL, - NULL, - herculesplus_speed_changed, - NULL, - NULL -}; diff --git a/backup code/video - Cópia/vid_herculesplus.h b/backup code/video - Cópia/vid_herculesplus.h deleted file mode 100644 index 72b47c35f..000000000 --- a/backup code/video - Cópia/vid_herculesplus.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: John Elliott - see COPYING for more details -*/ -extern const device_t herculesplus_device; diff --git a/backup code/video - Cópia/vid_icd2061.c b/backup code/video - Cópia/vid_icd2061.c deleted file mode 100644 index e8aaf05cb..000000000 --- a/backup code/video - Cópia/vid_icd2061.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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. - * - * ICD2061 clock generator emulation. - * - * Used by ET4000w32/p (Diamond Stealth 32) - * - * Version: @(#)vid_icd2061.c 1.0.2 2017/11/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "vid_icd2061.h" - - -void icd2061_write(icd2061_t *icd2061, int val) -{ - int q, p, m, a; - if ((val & 1) && !(icd2061->state & 1)) - { - if (!icd2061->status) - { - if (val & 2) - icd2061->unlock++; - else - { - if (icd2061->unlock >= 5) - { - icd2061->status = 1; - icd2061->pos = 0; - } - else - icd2061->unlock = 0; - } - } - else if (val & 1) - { - icd2061->data = (icd2061->data >> 1) | (((val & 2) ? 1 : 0) << 24); - icd2061->pos++; - if (icd2061->pos == 26) - { - a = (icd2061->data >> 21) & 0x7; - if (!(a & 4)) - { - q = (icd2061->data & 0x7f) - 2; - m = 1 << ((icd2061->data >> 7) & 0x7); - p = ((icd2061->data >> 10) & 0x7f) - 3; - if (icd2061->ctrl & (1 << a)) - p <<= 1; - icd2061->freq[a] = ((double)p / (double)q) * 2.0 * 14318184.0 / (double)m; - } - else if (a == 6) - { - icd2061->ctrl = val; - } - icd2061->unlock = icd2061->data = 0; - icd2061->status = 0; - } - } - } - icd2061->state = val; -} - -double icd2061_getfreq(icd2061_t *icd2061, int i) -{ - return icd2061->freq[i]; -} diff --git a/backup code/video - Cópia/vid_icd2061.h b/backup code/video - Cópia/vid_icd2061.h deleted file mode 100644 index acb6821cf..000000000 --- a/backup code/video - Cópia/vid_icd2061.h +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -typedef struct icd2061_t -{ - int state; - int status; - int pos; - int unlock; - uint32_t data; - - double freq[4]; - uint32_t ctrl; -} icd2061_t; - -void icd2061_write(icd2061_t *icd2061, int val); -double icd2061_getfreq(icd2061_t *icd2061, int i); diff --git a/backup code/video - Cópia/vid_ics2595.c b/backup code/video - Cópia/vid_ics2595.c deleted file mode 100644 index 029999de9..000000000 --- a/backup code/video - Cópia/vid_ics2595.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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. - * - * ICS2595 clock chip emulation. Used by ATI Mach64. - * - * Version: @(#)vid_ics2595.c 1.0.2 2017/11/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "vid_ics2595.h" - - -enum -{ - ICS2595_IDLE = 0, - ICS2595_WRITE, - ICS2595_READ -}; - - -static int ics2595_div[4] = {8, 4, 2, 1}; - - -void ics2595_write(ics2595_t *ics2595, int strobe, int dat) -{ - if (strobe) - { - if ((dat & 8) && !ics2595->oldfs3) /*Data clock*/ - { - switch (ics2595->state) - { - case ICS2595_IDLE: - ics2595->state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE; - ics2595->pos = 0; - break; - case ICS2595_WRITE: - ics2595->dat = (ics2595->dat >> 1); - if (dat & 4) - ics2595->dat |= (1 << 19); - ics2595->pos++; - if (ics2595->pos == 20) - { - int d, n, l; - l = (ics2595->dat >> 2) & 0xf; - n = ((ics2595->dat >> 7) & 255) + 257; - d = ics2595_div[(ics2595->dat >> 16) & 3]; - - ics2595->clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d; - ics2595->state = ICS2595_IDLE; - } - break; - } - } - - ics2595->oldfs2 = dat & 4; - ics2595->oldfs3 = dat & 8; - } - ics2595->output_clock = ics2595->clocks[dat]; -} diff --git a/backup code/video - Cópia/vid_ics2595.h b/backup code/video - Cópia/vid_ics2595.h deleted file mode 100644 index 5e5f1842d..000000000 --- a/backup code/video - Cópia/vid_ics2595.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -typedef struct ics2595_t -{ - int oldfs3, oldfs2; - int dat; - int pos; - int state; - - double clocks[16]; - double output_clock; -} ics2595_t; - -void ics2595_write(ics2595_t *ics2595, int strobe, int dat); diff --git a/backup code/video - Cópia/vid_incolor.c b/backup code/video - Cópia/vid_incolor.c deleted file mode 100644 index f1cf1c1a1..000000000 --- a/backup code/video - Cópia/vid_incolor.c +++ /dev/null @@ -1,1083 +0,0 @@ -/* - * 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. - * - * Hercules InColor emulation. - * - * Version: @(#)vid_incolor.c 1.0.10 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../lpt.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "video.h" -#include "vid_incolor.h" - - -/* extended CRTC registers */ -#define INCOLOR_CRTC_XMODE 20 /* xMode register */ -#define INCOLOR_CRTC_UNDER 21 /* Underline */ -#define INCOLOR_CRTC_OVER 22 /* Overstrike */ -#define INCOLOR_CRTC_EXCEPT 23 /* Exception */ -#define INCOLOR_CRTC_MASK 24 /* Plane display mask & write mask */ -#define INCOLOR_CRTC_RWCTRL 25 /* Read/write control */ -#define INCOLOR_CRTC_RWCOL 26 /* Read/write colour */ -#define INCOLOR_CRTC_PROTECT 27 /* Latch protect */ -#define INCOLOR_CRTC_PALETTE 28 /* Palette */ - -/* character width */ -#define INCOLOR_CW ((incolor->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) ? 8 : 9) - -/* mode control register */ -#define INCOLOR_CTRL_GRAPH 0x02 -#define INCOLOR_CTRL_ENABLE 0x08 -#define INCOLOR_CTRL_BLINK 0x20 -#define INCOLOR_CTRL_PAGE1 0x80 - -/* CRTC status register */ -#define INCOLOR_STATUS_HSYNC 0x01 /* horizontal sync */ -#define INCOLOR_STATUS_LIGHT 0x02 -#define INCOLOR_STATUS_VIDEO 0x08 -#define INCOLOR_STATUS_ID 0x50 /* Card identification */ -#define INCOLOR_STATUS_VSYNC 0x80 /* -vertical sync */ - -/* configuration switch register */ -#define INCOLOR_CTRL2_GRAPH 0x01 -#define INCOLOR_CTRL2_PAGE1 0x02 - -/* extended mode register */ -#define INCOLOR_XMODE_RAMFONT 0x01 -#define INCOLOR_XMODE_90COL 0x02 - - -/* Read/write control */ -#define INCOLOR_RWCTRL_WRMODE 0x30 -#define INCOLOR_RWCTRL_POLARITY 0x40 - -/* exception register */ -#define INCOLOR_EXCEPT_CURSOR 0x0F /* Cursor colour */ -#define INCOLOR_EXCEPT_PALETTE 0x10 /* Enable palette register */ -#define INCOLOR_EXCEPT_ALTATTR 0x20 /* Use alternate attributes */ - - - -/* Default palette */ -static unsigned char defpal[16] = -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F -}; - -static uint32_t incolor_rgb[64]; - -/* Mapping of inks to RGB */ -static unsigned char init_rgb[64][3] = -{ - /* rgbRGB */ - { 0x00, 0x00, 0x00 }, /* 000000 */ - { 0x00, 0x00, 0xaa }, /* 000001 */ - { 0x00, 0xaa, 0x00 }, /* 000010 */ - { 0x00, 0xaa, 0xaa }, /* 000011 */ - { 0xaa, 0x00, 0x00 }, /* 000100 */ - { 0xaa, 0x00, 0xaa }, /* 000101 */ - { 0xaa, 0xaa, 0x00 }, /* 000110 */ - { 0xaa, 0xaa, 0xaa }, /* 000111 */ - { 0x00, 0x00, 0x55 }, /* 001000 */ - { 0x00, 0x00, 0xff }, /* 001001 */ - { 0x00, 0xaa, 0x55 }, /* 001010 */ - { 0x00, 0xaa, 0xff }, /* 001011 */ - { 0xaa, 0x00, 0x55 }, /* 001100 */ - { 0xaa, 0x00, 0xff }, /* 001101 */ - { 0xaa, 0xaa, 0x55 }, /* 001110 */ - { 0xaa, 0xaa, 0xff }, /* 001111 */ - { 0x00, 0x55, 0x00 }, /* 010000 */ - { 0x00, 0x55, 0xaa }, /* 010001 */ - { 0x00, 0xff, 0x00 }, /* 010010 */ - { 0x00, 0xff, 0xaa }, /* 010011 */ - { 0xaa, 0x55, 0x00 }, /* 010100 */ - { 0xaa, 0x55, 0xaa }, /* 010101 */ - { 0xaa, 0xff, 0x00 }, /* 010110 */ - { 0xaa, 0xff, 0xaa }, /* 010111 */ - { 0x00, 0x55, 0x55 }, /* 011000 */ - { 0x00, 0x55, 0xff }, /* 011001 */ - { 0x00, 0xff, 0x55 }, /* 011010 */ - { 0x00, 0xff, 0xff }, /* 011011 */ - { 0xaa, 0x55, 0x55 }, /* 011100 */ - { 0xaa, 0x55, 0xff }, /* 011101 */ - { 0xaa, 0xff, 0x55 }, /* 011110 */ - { 0xaa, 0xff, 0xff }, /* 011111 */ - { 0x55, 0x00, 0x00 }, /* 100000 */ - { 0x55, 0x00, 0xaa }, /* 100001 */ - { 0x55, 0xaa, 0x00 }, /* 100010 */ - { 0x55, 0xaa, 0xaa }, /* 100011 */ - { 0xff, 0x00, 0x00 }, /* 100100 */ - { 0xff, 0x00, 0xaa }, /* 100101 */ - { 0xff, 0xaa, 0x00 }, /* 100110 */ - { 0xff, 0xaa, 0xaa }, /* 100111 */ - { 0x55, 0x00, 0x55 }, /* 101000 */ - { 0x55, 0x00, 0xff }, /* 101001 */ - { 0x55, 0xaa, 0x55 }, /* 101010 */ - { 0x55, 0xaa, 0xff }, /* 101011 */ - { 0xff, 0x00, 0x55 }, /* 101100 */ - { 0xff, 0x00, 0xff }, /* 101101 */ - { 0xff, 0xaa, 0x55 }, /* 101110 */ - { 0xff, 0xaa, 0xff }, /* 101111 */ - { 0x55, 0x55, 0x00 }, /* 110000 */ - { 0x55, 0x55, 0xaa }, /* 110001 */ - { 0x55, 0xff, 0x00 }, /* 110010 */ - { 0x55, 0xff, 0xaa }, /* 110011 */ - { 0xff, 0x55, 0x00 }, /* 110100 */ - { 0xff, 0x55, 0xaa }, /* 110101 */ - { 0xff, 0xff, 0x00 }, /* 110110 */ - { 0xff, 0xff, 0xaa }, /* 110111 */ - { 0x55, 0x55, 0x55 }, /* 111000 */ - { 0x55, 0x55, 0xff }, /* 111001 */ - { 0x55, 0xff, 0x55 }, /* 111010 */ - { 0x55, 0xff, 0xff }, /* 111011 */ - { 0xff, 0x55, 0x55 }, /* 111100 */ - { 0xff, 0x55, 0xff }, /* 111101 */ - { 0xff, 0xff, 0x55 }, /* 111110 */ - { 0xff, 0xff, 0xff }, /* 111111 */ -}; - - - -typedef struct incolor_t -{ - mem_mapping_t mapping; - - uint8_t crtc[32]; - int crtcreg; - - uint8_t ctrl, ctrl2, stat; - - int64_t dispontime, dispofftime; - int64_t vidtime; - - int firstline, lastline; - - int linepos, displine; - int vc, sc; - uint16_t ma, maback; - int con, coff, cursoron; - int dispon, blink; - int64_t vsynctime; - int vadj; - - uint8_t palette[16]; /* EGA-style 16 -> 64 palette registers */ - uint8_t palette_idx; /* Palette write index */ - uint8_t latch[4]; /* Memory read/write latches */ - uint8_t *vram; -} incolor_t; - -void incolor_recalctimings(incolor_t *incolor); -void incolor_write(uint32_t addr, uint8_t val, void *p); -uint8_t incolor_read(uint32_t addr, void *p); - - -void incolor_out(uint16_t addr, uint8_t val, void *p) -{ - incolor_t *incolor = (incolor_t *)p; - switch (addr) - { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - incolor->crtcreg = val & 31; - return; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - if (incolor->crtcreg > 28) return; - /* Palette load register */ - if (incolor->crtcreg == INCOLOR_CRTC_PALETTE) - { - incolor->palette[incolor->palette_idx % 16] = val; - ++incolor->palette_idx; - } - incolor->crtc[incolor->crtcreg] = val; - if (incolor->crtc[10] == 6 && incolor->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ - { - incolor->crtc[10] = 0xb; - incolor->crtc[11] = 0xc; - } - incolor_recalctimings(incolor); - return; - case 0x3b8: - incolor->ctrl = val; - return; - case 0x3bf: - incolor->ctrl2 = val; - if (val & 2) - mem_mapping_set_addr(&incolor->mapping, 0xb0000, 0x10000); - else - mem_mapping_set_addr(&incolor->mapping, 0xb0000, 0x08000); - return; - } -} - -uint8_t incolor_in(uint16_t addr, void *p) -{ - incolor_t *incolor = (incolor_t *)p; - switch (addr) - { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - return incolor->crtcreg; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - if (incolor->crtcreg > 28) return 0xff; - incolor->palette_idx = 0; /* Read resets the palette index */ - return incolor->crtc[incolor->crtcreg]; - case 0x3ba: - /* 0x50: InColor card identity */ - return (incolor->stat & 0xf) | ((incolor->stat & 8) << 4) | 0x50; - } - return 0xff; -} - -void incolor_write(uint32_t addr, uint8_t val, void *p) -{ - incolor_t *incolor = (incolor_t *)p; - - int plane; - - unsigned char wmask = incolor->crtc[INCOLOR_CRTC_MASK]; - unsigned char wmode = incolor->crtc[INCOLOR_CRTC_RWCTRL] & INCOLOR_RWCTRL_WRMODE; - unsigned char fg = incolor->crtc[INCOLOR_CRTC_RWCOL] & 0x0F; - unsigned char bg = (incolor->crtc[INCOLOR_CRTC_RWCOL] >> 4)&0x0F; - unsigned char w = 0; - unsigned char vmask; /* Mask of bit within byte */ - unsigned char pmask; /* Mask of plane within colour value */ - unsigned char latch; - - egawrites++; - - addr &= 0xFFFF; - - /* In text mode, writes to the bottom 16k always touch all 4 planes */ - if (!(incolor->ctrl & INCOLOR_CTRL_GRAPH) && addr < 0x4000) - { - incolor->vram[addr] = val; - return; - } - - /* There are four write modes: - * 0: 1 => foreground, 0 => background - * 1: 1 => foreground, 0 => source latch - * 2: 1 => source latch, 0 => background - * 3: 1 => source latch, 0 => ~source latch - */ - pmask = 1; - for (plane = 0; plane < 4; pmask <<= 1, wmask >>= 1, addr += 0x10000, - plane++) - { - if (wmask & 0x10) /* Ignore writes to selected plane */ - { - continue; - } - latch = incolor->latch[plane]; - for (vmask = 0x80; vmask != 0; vmask >>= 1) - { - switch (wmode) - { - case 0x00: - if (val & vmask) w = (fg & pmask); - else w = (bg & pmask); - break; - case 0x10: - if (val & vmask) w = (fg & pmask); - else w = (latch & vmask); - break; - case 0x20: - if (val & vmask) w = (latch & vmask); - else w = (bg & pmask); - break; - case 0x30: - if (val & vmask) w = (latch & vmask); - else w = ((~latch) & vmask); - break; - } - /* w is nonzero to write a 1, zero to write a 0 */ - if (w) incolor->vram[addr] |= vmask; - else incolor->vram[addr] &= ~vmask; - } - } -} - -uint8_t incolor_read(uint32_t addr, void *p) -{ - incolor_t *incolor = (incolor_t *)p; - unsigned plane; - unsigned char lp = incolor->crtc[INCOLOR_CRTC_PROTECT]; - unsigned char value = 0; - unsigned char dc; /* "don't care" register */ - unsigned char bg; /* background colour */ - unsigned char fg; - unsigned char mask, pmask; - - egareads++; - - addr &= 0xFFFF; - /* Read the four planes into latches */ - for (plane = 0; plane < 4; plane++, addr += 0x10000) - { - incolor->latch[plane] &= lp; - incolor->latch[plane] |= (incolor->vram[addr] & ~lp); - } - addr &= 0xFFFF; - /* In text mode, reads from the bottom 16k assume all planes have - * the same contents */ - if (!(incolor->ctrl & INCOLOR_CTRL_GRAPH) && addr < 0x4000) - { - return incolor->latch[0]; - } - /* For each pixel, work out if its colour matches the background */ - for (mask = 0x80; mask != 0; mask >>= 1) - { - fg = 0; - dc = incolor->crtc[INCOLOR_CRTC_RWCTRL] & 0x0F; - bg = (incolor->crtc[INCOLOR_CRTC_RWCOL] >> 4) & 0x0F; - for (plane = 0, pmask = 1; plane < 4; plane++, pmask <<= 1) - { - if (dc & pmask) - { - fg |= (bg & pmask); - } - else if (incolor->latch[plane] & mask) - { - fg |= pmask; - } - } - if (bg == fg) value |= mask; - } - if (incolor->crtc[INCOLOR_CRTC_RWCTRL] & INCOLOR_RWCTRL_POLARITY) - { - value = ~value; - } - return value; -} - - - -void incolor_recalctimings(incolor_t *incolor) -{ - double disptime; - double _dispontime, _dispofftime; - disptime = incolor->crtc[0] + 1; - _dispontime = incolor->crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - incolor->dispontime = (int64_t)(_dispontime * (1 << TIMER_SHIFT)); - incolor->dispofftime = (int64_t)(_dispofftime * (1 << TIMER_SHIFT)); -} - - -static void incolor_draw_char_rom(incolor_t *incolor, int x, uint8_t chr, uint8_t attr) -{ - unsigned i; - int elg, blk; - unsigned ull; - unsigned val; - unsigned ifg, ibg; - const unsigned char *fnt; - uint32_t fg, bg; - int cw = INCOLOR_CW; - - blk = 0; - if (incolor->ctrl & INCOLOR_CTRL_BLINK) - { - if (attr & 0x80) - { - blk = (incolor->blink & 16); - } - attr &= 0x7f; - } - - if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR) - { - /* MDA-compatible attributes */ - ibg = 0; - ifg = 7; - if ((attr & 0x77) == 0x70) /* Invert */ - { - ifg = 0; - ibg = 7; - } - if (attr & 8) - { - ifg |= 8; /* High intensity FG */ - } - if (attr & 0x80) - { - ibg |= 8; /* High intensity BG */ - } - if ((attr & 0x77) == 0) /* Blank */ - { - ifg = ibg; - } - ull = ((attr & 0x07) == 1) ? 13 : 0xffff; - } - else - { - /* CGA-compatible attributes */ - ull = 0xffff; - ifg = attr & 0x0F; - ibg = (attr >> 4) & 0x0F; - } - if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) - { - fg = incolor_rgb[incolor->palette[ifg]]; - bg = incolor_rgb[incolor->palette[ibg]]; - } - else - { - fg = incolor_rgb[defpal[ifg]]; - bg = incolor_rgb[defpal[ibg]]; - } - - /* ELG set to stretch 8px character to 9px */ - if (incolor->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) - { - elg = 0; - } - else - { - elg = ((chr >= 0xc0) && (chr <= 0xdf)); - } - - fnt = &(fontdatm[chr][incolor->sc]); - - if (blk) - { - val = 0x000; /* Blinking, draw all background */ - } - else if (incolor->sc == ull) - { - val = 0x1ff; /* Underscore, draw all foreground */ - } - else - { - val = fnt[0] << 1; - - if (elg) - { - val |= (val >> 1) & 1; - } - } - for (i = 0; i < cw; i++) - { - ((uint32_t *)buffer32->line[incolor->displine])[x * cw + i] = (val & 0x100) ? fg : bg; - val = val << 1; - } -} - - -static void incolor_draw_char_ram4(incolor_t *incolor, int x, uint8_t chr, uint8_t attr) -{ - unsigned i; - int elg, blk; - unsigned ull; - unsigned val[4]; - unsigned ifg, ibg, cfg, pmask, plane; - const unsigned char *fnt; - uint32_t fg; - int cw = INCOLOR_CW; - int blink = incolor->ctrl & INCOLOR_CTRL_BLINK; - int altattr = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR; - int palette = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE; - - blk = 0; - if (blink) - { - if (attr & 0x80) - { - blk = (incolor->blink & 16); - } - attr &= 0x7f; - } - - if (altattr) - { - /* MDA-compatible attributes */ - ibg = 0; - ifg = 7; - if ((attr & 0x77) == 0x70) /* Invert */ - { - ifg = 0; - ibg = 7; - } - if (attr & 8) - { - ifg |= 8; /* High intensity FG */ - } - if (attr & 0x80) - { - ibg |= 8; /* High intensity BG */ - } - if ((attr & 0x77) == 0) /* Blank */ - { - ifg = ibg; - } - ull = ((attr & 0x07) == 1) ? 13 : 0xffff; - } - else - { - /* CGA-compatible attributes */ - ull = 0xffff; - ifg = attr & 0x0F; - ibg = (attr >> 4) & 0x0F; - } - if (incolor->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) - { - elg = 0; - } - else - { - elg = ((chr >= 0xc0) && (chr <= 0xdf)); - } - fnt = incolor->vram + 0x4000 + 16 * chr + incolor->sc; - - if (blk) - { - /* Blinking, draw all background */ - val[0] = val[1] = val[2] = val[3] = 0x000; - } - else if (incolor->sc == ull) - { - /* Underscore, draw all foreground */ - val[0] = val[1] = val[2] = val[3] = 0x1ff; - } - else - { - val[0] = fnt[0x00000] << 1; - val[1] = fnt[0x10000] << 1; - val[2] = fnt[0x20000] << 1; - val[3] = fnt[0x30000] << 1; - - if (elg) - { - val[0] |= (val[0] >> 1) & 1; - val[1] |= (val[1] >> 1) & 1; - val[2] |= (val[2] >> 1) & 1; - val[3] |= (val[3] >> 1) & 1; - } - } - for (i = 0; i < cw; i++) - { - /* Generate pixel colour */ - cfg = 0; - pmask = 1; - for (plane = 0; plane < 4; plane++, pmask = pmask << 1) - { - if (val[plane] & 0x100) cfg |= (ifg & pmask); - else cfg |= (ibg & pmask); - } - /* cfg = colour of foreground pixels */ - if (altattr && (attr & 0x77) == 0) cfg = ibg; /* 'blank' attribute */ - if (palette) - { - fg = incolor_rgb[incolor->palette[cfg]]; - } - else - { - fg = incolor_rgb[defpal[cfg]]; - } - - ((uint32_t *)buffer32->line[incolor->displine])[x * cw + i] = fg; - val[0] = val[0] << 1; - val[1] = val[1] << 1; - val[2] = val[2] << 1; - val[3] = val[3] << 1; - } -} - - -static void incolor_draw_char_ram48(incolor_t *incolor, int x, uint8_t chr, uint8_t attr) -{ - unsigned i; - int elg, blk, ul, ol, bld; - unsigned ull, oll, ulc = 0, olc = 0; - unsigned val[4]; - unsigned ifg = 0, ibg, cfg, pmask, plane; - const unsigned char *fnt; - uint32_t fg; - int cw = INCOLOR_CW; - int blink = incolor->ctrl & INCOLOR_CTRL_BLINK; - int altattr = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR; - int palette = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE; - int font = (attr & 0x0F); - - if (font >= 12) font &= 7; - - blk = 0; - if (blink && altattr) - { - if (attr & 0x40) - { - blk = (incolor->blink & 16); - } - attr &= 0x7f; - } - if (altattr) - { - /* MDA-compatible attributes */ - if (blink) - { - ibg = (attr & 0x80) ? 8 : 0; - bld = 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; - } - else - { - bld = (attr & 0x80) ? 1 : 0; - ibg = (attr & 0x40) ? 0x0F : 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; - } - } - else - { - /* CGA-compatible attributes */ - ibg = 0; - ifg = (attr >> 4) & 0x0F; - ol = 0; - ul = 0; - bld = 0; - } - if (ul) - { - ull = incolor->crtc[INCOLOR_CRTC_UNDER] & 0x0F; - ulc = (incolor->crtc[INCOLOR_CRTC_UNDER] >> 4) & 0x0F; - if (ulc == 0) ulc = 7; - } - else - { - ull = 0xFFFF; - } - if (ol) - { - oll = incolor->crtc[INCOLOR_CRTC_OVER] & 0x0F; - olc = (incolor->crtc[INCOLOR_CRTC_OVER] >> 4) & 0x0F; - if (olc == 0) olc = 7; - } - else - { - oll = 0xFFFF; - } - - if (incolor->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) - { - elg = 0; - } - else - { - elg = ((chr >= 0xc0) && (chr <= 0xdf)); - } - fnt = incolor->vram + 0x4000 + 16 * chr + 4096 * font + incolor->sc; - - if (blk) - { - /* Blinking, draw all background */ - val[0] = val[1] = val[2] = val[3] = 0x000; - } - else if (incolor->sc == ull) - { - /* Underscore, draw all foreground */ - val[0] = val[1] = val[2] = val[3] = 0x1ff; - } - else - { - val[0] = fnt[0x00000] << 1; - val[1] = fnt[0x10000] << 1; - val[2] = fnt[0x20000] << 1; - val[3] = fnt[0x30000] << 1; - - if (elg) - { - val[0] |= (val[0] >> 1) & 1; - val[1] |= (val[1] >> 1) & 1; - val[2] |= (val[2] >> 1) & 1; - val[3] |= (val[3] >> 1) & 1; - } - if (bld) - { - val[0] |= (val[0] >> 1); - val[1] |= (val[1] >> 1); - val[2] |= (val[2] >> 1); - val[3] |= (val[3] >> 1); - } - } - for (i = 0; i < cw; i++) - { - /* Generate pixel colour */ - cfg = 0; - pmask = 1; - if (incolor->sc == oll) - { - cfg = olc ^ ibg; /* Strikethrough */ - } - else if (incolor->sc == ull) - { - cfg = ulc ^ ibg; /* Underline */ - } - else - { - for (plane = 0; plane < 4; plane++, pmask = pmask << 1) - { - if (val[plane] & 0x100) - { - if (altattr) cfg |= ((~ibg) & pmask); - else cfg |= ((~ifg) & pmask); - } - else if (altattr) cfg |= (ibg & pmask); - } - } - if (palette) - { - fg = incolor_rgb[incolor->palette[cfg]]; - } - else - { - fg = incolor_rgb[defpal[cfg]]; - } - - ((uint32_t *)buffer32->line[incolor->displine])[x * cw + i] = fg; - val[0] = val[0] << 1; - val[1] = val[1] << 1; - val[2] = val[2] << 1; - val[3] = val[3] << 1; - } -} - - - - - - -static void incolor_text_line(incolor_t *incolor, uint16_t ca) -{ - int drawcursor; - int x, c; - uint8_t chr, attr; - uint32_t col; - - for (x = 0; x < incolor->crtc[1]; x++) - { - chr = incolor->vram[(incolor->ma << 1) & 0xfff]; - attr = incolor->vram[((incolor->ma << 1) + 1) & 0xfff]; - - drawcursor = ((incolor->ma == ca) && incolor->con && incolor->cursoron); - - switch (incolor->crtc[INCOLOR_CRTC_XMODE] & 5) - { - case 0: - case 4: /* ROM font */ - incolor_draw_char_rom(incolor, x, chr, attr); - break; - case 1: /* 4k RAMfont */ - incolor_draw_char_ram4(incolor, x, chr, attr); - break; - case 5: /* 48k RAMfont */ - incolor_draw_char_ram48(incolor, x, chr, attr); - break; - - } - ++incolor->ma; - if (drawcursor) - { - int cw = INCOLOR_CW; - uint8_t ink = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_CURSOR; - if (ink == 0) ink = (attr & 0x08) | 7; - - /* In MDA-compatible mode, cursor brightness comes from - * background */ - if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR) - { - ink = (attr & 0x08) | (ink & 7); - } - if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) - { - col = incolor_rgb[incolor->palette[ink]]; - } - else - { - col = incolor_rgb[defpal[ink]]; - } - for (c = 0; c < cw; c++) - { - ((uint32_t *)buffer32->line[incolor->displine])[x * cw + c] = col; - } - } - } -} - - -static void incolor_graphics_line(incolor_t *incolor) -{ - uint8_t mask; - uint16_t ca; - int x, c, plane, col; - uint8_t ink; - uint16_t val[4]; - - /* Graphics mode. */ - ca = (incolor->sc & 3) * 0x2000; - if ((incolor->ctrl & INCOLOR_CTRL_PAGE1) && (incolor->ctrl2 & INCOLOR_CTRL2_PAGE1)) - ca += 0x8000; - - for (x = 0; x < incolor->crtc[1]; x++) - { - mask = incolor->crtc[INCOLOR_CRTC_MASK]; /* Planes to display */ - for (plane = 0; plane < 4; plane++, mask = mask >> 1) - { - if (mask & 1) - val[plane] = (incolor->vram[((incolor->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) | - incolor->vram[((incolor->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; - else val[plane] = 0; - } - incolor->ma++; - for (c = 0; c < 16; c++) - { - ink = 0; - for (plane = 0; plane < 4; plane++) - { - ink = ink >> 1; - if (val[plane] & 0x8000) ink |= 8; - val[plane] = val[plane] << 1; - } - /* Is palette in use? */ - if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) - col = incolor->palette[ink]; - else col = defpal[ink]; - - ((uint32_t *)buffer32->line[incolor->displine])[(x << 4) + c] = incolor_rgb[col]; - } - } -} - -void incolor_poll(void *p) -{ - incolor_t *incolor = (incolor_t *)p; - uint16_t ca = (incolor->crtc[15] | (incolor->crtc[14] << 8)) & 0x3fff; - int x; - int oldvc; - int oldsc; - - if (!incolor->linepos) - { - incolor->vidtime += incolor->dispofftime; - incolor->stat |= 1; - incolor->linepos = 1; - oldsc = incolor->sc; - if ((incolor->crtc[8] & 3) == 3) - incolor->sc = (incolor->sc << 1) & 7; - if (incolor->dispon) - { - if (incolor->displine < incolor->firstline) - { - incolor->firstline = incolor->displine; - video_wait_for_buffer(); - } - incolor->lastline = incolor->displine; - if ((incolor->ctrl & INCOLOR_CTRL_GRAPH) && (incolor->ctrl2 & INCOLOR_CTRL2_GRAPH)) - { - incolor_graphics_line(incolor); - } - else - { - incolor_text_line(incolor, ca); - } - } - incolor->sc = oldsc; - if (incolor->vc == incolor->crtc[7] && !incolor->sc) - { - incolor->stat |= 8; - } - incolor->displine++; - if (incolor->displine >= 500) - incolor->displine = 0; - } - else - { - incolor->vidtime += incolor->dispontime; - if (incolor->dispon) - incolor->stat &= ~1; - incolor->linepos = 0; - if (incolor->vsynctime) - { - incolor->vsynctime--; - if (!incolor->vsynctime) - { - incolor->stat &= ~8; - } - } - if (incolor->sc == (incolor->crtc[11] & 31) || ((incolor->crtc[8] & 3) == 3 && incolor->sc == ((incolor->crtc[11] & 31) >> 1))) - { - incolor->con = 0; - incolor->coff = 1; - } - if (incolor->vadj) - { - incolor->sc++; - incolor->sc &= 31; - incolor->ma = incolor->maback; - incolor->vadj--; - if (!incolor->vadj) - { - incolor->dispon = 1; - incolor->ma = incolor->maback = (incolor->crtc[13] | (incolor->crtc[12] << 8)) & 0x3fff; - incolor->sc = 0; - } - } - else if (incolor->sc == incolor->crtc[9] || ((incolor->crtc[8] & 3) == 3 && incolor->sc == (incolor->crtc[9] >> 1))) - { - incolor->maback = incolor->ma; - incolor->sc = 0; - oldvc = incolor->vc; - incolor->vc++; - incolor->vc &= 127; - if (incolor->vc == incolor->crtc[6]) - incolor->dispon = 0; - if (oldvc == incolor->crtc[4]) - { - incolor->vc = 0; - incolor->vadj = incolor->crtc[5]; - if (!incolor->vadj) incolor->dispon=1; - if (!incolor->vadj) incolor->ma = incolor->maback = (incolor->crtc[13] | (incolor->crtc[12] << 8)) & 0x3fff; - if ((incolor->crtc[10] & 0x60) == 0x20) incolor->cursoron = 0; - else incolor->cursoron = incolor->blink & 16; - } - if (incolor->vc == incolor->crtc[7]) - { - incolor->dispon = 0; - incolor->displine = 0; - incolor->vsynctime = 16; - if (incolor->crtc[7]) - { - if ((incolor->ctrl & INCOLOR_CTRL_GRAPH) && (incolor->ctrl2 & INCOLOR_CTRL2_GRAPH)) - { - x = incolor->crtc[1] << 4; - } - else - { - x = incolor->crtc[1] * 9; - } - incolor->lastline++; - if ((x != xsize) || ((incolor->lastline - incolor->firstline) != ysize) || video_force_resize_get()) - { - xsize = x; - ysize = incolor->lastline - incolor->firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen(0, incolor->firstline, 0, incolor->lastline - incolor->firstline, xsize, incolor->lastline - incolor->firstline); - frames++; - if ((incolor->ctrl & INCOLOR_CTRL_GRAPH) && (incolor->ctrl2 & INCOLOR_CTRL2_GRAPH)) - { - video_res_x = incolor->crtc[1] * 16; - video_res_y = incolor->crtc[6] * 4; - video_bpp = 1; - } - else - { - video_res_x = incolor->crtc[1]; - video_res_y = incolor->crtc[6]; - video_bpp = 0; - } - } - incolor->firstline = 1000; - incolor->lastline = 0; - incolor->blink++; - } - } - else - { - incolor->sc++; - incolor->sc &= 31; - incolor->ma = incolor->maback; - } - if ((incolor->sc == (incolor->crtc[10] & 31) || ((incolor->crtc[8] & 3) == 3 && incolor->sc == ((incolor->crtc[10] & 31) >> 1)))) - { - incolor->con = 1; - } - } -} - -void *incolor_init(const device_t *info) -{ - int c; - incolor_t *incolor = malloc(sizeof(incolor_t)); - memset(incolor, 0, sizeof(incolor_t)); - - incolor->vram = malloc(0x40000); /* 4 planes of 64k */ - - timer_add(incolor_poll, &incolor->vidtime, TIMER_ALWAYS_ENABLED, incolor); - mem_mapping_add(&incolor->mapping, 0xb0000, 0x08000, incolor_read, NULL, NULL, incolor_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, incolor); - io_sethandler(0x03b0, 0x0010, incolor_in, NULL, NULL, incolor_out, NULL, NULL, incolor); - - for (c = 0; c < 64; c++) - { - incolor_rgb[c] = makecol32(init_rgb[c][0], init_rgb[c][1], init_rgb[c][2]); - } - -/* Initialise CRTC regs to safe values */ - incolor->crtc[INCOLOR_CRTC_MASK ] = 0x0F; /* All planes displayed */ - incolor->crtc[INCOLOR_CRTC_RWCTRL] = INCOLOR_RWCTRL_POLARITY; - incolor->crtc[INCOLOR_CRTC_RWCOL ] = 0x0F; /* White on black */ - incolor->crtc[INCOLOR_CRTC_EXCEPT] = INCOLOR_EXCEPT_ALTATTR; - for (c = 0; c < 16; c++) - { - incolor->palette[c] = defpal[c]; - } - incolor->palette_idx = 0; - - lpt3_init(0x3BC); - - return incolor; -} - -void incolor_close(void *p) -{ - incolor_t *incolor = (incolor_t *)p; - - free(incolor->vram); - free(incolor); -} - -void incolor_speed_changed(void *p) -{ - incolor_t *incolor = (incolor_t *)p; - - incolor_recalctimings(incolor); -} - -const device_t incolor_device = -{ - "Hercules InColor", - DEVICE_ISA, 0, - incolor_init, incolor_close, NULL, - NULL, - incolor_speed_changed, - NULL, - NULL -}; diff --git a/backup code/video - Cópia/vid_incolor.h b/backup code/video - Cópia/vid_incolor.h deleted file mode 100644 index d75a97186..000000000 --- a/backup code/video - Cópia/vid_incolor.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: John Elliott - see COPYING for more details -*/ -extern const device_t incolor_device; diff --git a/backup code/video - Cópia/vid_mda.c b/backup code/video - Cópia/vid_mda.c deleted file mode 100644 index 51921bd78..000000000 --- a/backup code/video - Cópia/vid_mda.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * 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. - * - * MDA emulation. - * - * Version: @(#)vid_mda.c 1.0.11 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../lpt.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "video.h" -#include "vid_mda.h" - - -typedef struct mda_t -{ - mem_mapping_t mapping; - - uint8_t crtc[32]; - int crtcreg; - - uint8_t ctrl, stat; - - int64_t dispontime, dispofftime; - int64_t vidtime; - - int firstline, lastline; - - int linepos, displine; - int vc, sc; - uint16_t ma, maback; - int con, coff, cursoron; - int dispon, blink; - int64_t vsynctime; - int vadj; - - uint8_t *vram; -} mda_t; - -static int mdacols[256][2][2]; - -void mda_recalctimings(mda_t *mda); - -void mda_out(uint16_t addr, uint8_t val, void *p) -{ - mda_t *mda = (mda_t *)p; - switch (addr) - { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - mda->crtcreg = val & 31; - return; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - mda->crtc[mda->crtcreg] = val; - if (mda->crtc[10] == 6 && mda->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ - { - mda->crtc[10] = 0xb; - mda->crtc[11] = 0xc; - } - mda_recalctimings(mda); - return; - case 0x3b8: - mda->ctrl = val; - return; - } -} - -uint8_t mda_in(uint16_t addr, void *p) -{ - mda_t *mda = (mda_t *)p; - switch (addr) - { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - return mda->crtcreg; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - return mda->crtc[mda->crtcreg]; - case 0x3ba: - return mda->stat | 0xF0; - } - return 0xff; -} - -void mda_write(uint32_t addr, uint8_t val, void *p) -{ - mda_t *mda = (mda_t *)p; - egawrites++; - mda->vram[addr & 0xfff] = val; -} - -uint8_t mda_read(uint32_t addr, void *p) -{ - mda_t *mda = (mda_t *)p; - egareads++; - return mda->vram[addr & 0xfff]; -} - -void mda_recalctimings(mda_t *mda) -{ - double _dispontime, _dispofftime, disptime; - disptime = mda->crtc[0] + 1; - _dispontime = mda->crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - mda->dispontime = (int64_t)(_dispontime * (1 << TIMER_SHIFT)); - mda->dispofftime = (int64_t)(_dispofftime * (1 << TIMER_SHIFT)); -} - -void mda_poll(void *p) -{ - mda_t *mda = (mda_t *)p; - uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - int oldsc; - int blink; - if (!mda->linepos) - { - mda->vidtime += mda->dispofftime; - mda->stat |= 1; - mda->linepos = 1; - oldsc = mda->sc; - if ((mda->crtc[8] & 3) == 3) - mda->sc = (mda->sc << 1) & 7; - if (mda->dispon) - { - if (mda->displine < mda->firstline) - { - mda->firstline = mda->displine; - } - mda->lastline = mda->displine; - for (x = 0; x < mda->crtc[1]; x++) - { - chr = mda->vram[(mda->ma << 1) & 0xfff]; - attr = mda->vram[((mda->ma << 1) + 1) & 0xfff]; - drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron); - blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); - if (mda->sc == 12 && ((attr & 7) == 1)) - { - for (c = 0; c < 9; c++) - buffer->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1]; - } - else - { - for (c = 0; c < 8; c++) - buffer->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0]; - if ((chr & ~0x1f) == 0xc0) buffer->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1]; - else buffer->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0]; - } - mda->ma++; - if (drawcursor) - { - for (c = 0; c < 9; c++) - buffer->line[mda->displine][(x * 9) + c] ^= mdacols[attr][0][1]; - } - } - } - mda->sc = oldsc; - if (mda->vc == mda->crtc[7] && !mda->sc) - { - mda->stat |= 8; - } - mda->displine++; - if (mda->displine >= 500) - mda->displine=0; - } - else - { - mda->vidtime += mda->dispontime; - if (mda->dispon) mda->stat&=~1; - mda->linepos=0; - if (mda->vsynctime) - { - mda->vsynctime--; - if (!mda->vsynctime) - { - mda->stat&=~8; - } - } - if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) - { - mda->con = 0; - mda->coff = 1; - } - if (mda->vadj) - { - mda->sc++; - mda->sc &= 31; - mda->ma = mda->maback; - mda->vadj--; - if (!mda->vadj) - { - mda->dispon = 1; - mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - mda->sc = 0; - } - } - else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) - { - mda->maback = mda->ma; - mda->sc = 0; - oldvc = mda->vc; - mda->vc++; - mda->vc &= 127; - if (mda->vc == mda->crtc[6]) - mda->dispon=0; - if (oldvc == mda->crtc[4]) - { - mda->vc = 0; - mda->vadj = mda->crtc[5]; - if (!mda->vadj) mda->dispon = 1; - if (!mda->vadj) mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - if ((mda->crtc[10] & 0x60) == 0x20) mda->cursoron = 0; - else mda->cursoron = mda->blink & 16; - } - if (mda->vc == mda->crtc[7]) - { - mda->dispon = 0; - mda->displine = 0; - mda->vsynctime = 16; - if (mda->crtc[7]) - { - x = mda->crtc[1] * 9; - mda->lastline++; - if ((x != xsize) || ((mda->lastline - mda->firstline) != ysize) || video_force_resize_get()) - { - xsize = x; - ysize = mda->lastline - mda->firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen_8(0, mda->firstline, 0, ysize, xsize, ysize); - frames++; - video_res_x = mda->crtc[1]; - video_res_y = mda->crtc[6]; - video_bpp = 0; - } - mda->firstline = 1000; - mda->lastline = 0; - mda->blink++; - } - } - else - { - mda->sc++; - mda->sc &= 31; - mda->ma = mda->maback; - } - if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1)))) - { - mda->con = 1; - } - } -} - - -void *mda_init(const device_t *info) -{ - int c; - mda_t *mda = malloc(sizeof(mda_t)); - memset(mda, 0, sizeof(mda_t)); - - mda->vram = malloc(0x1000); - - timer_add(mda_poll, &mda->vidtime, TIMER_ALWAYS_ENABLED, mda); - mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda); - io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda); - - for (c = 0; c < 256; c++) - { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; - if (c & 8) mdacols[c][0][1] = 15 + 16; - else mdacols[c][0][1] = 7 + 16; - } - mdacols[0x70][0][1] = 16; - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15; - mdacols[0xF0][0][1] = 16; - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15; - mdacols[0x78][0][1] = 16 + 7; - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15; - mdacols[0xF8][0][1] = 16 + 7; - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; - - overscan_x = overscan_y = 0; - - cga_palette = device_get_config_int("rgb_type") << 1; - if (cga_palette > 6) - { - cga_palette = 0; - } - cgapal_rebuild(); - - lpt3_init(0x3BC); - - return mda; -} - -void mda_close(void *p) -{ - mda_t *mda = (mda_t *)p; - - free(mda->vram); - free(mda); -} - -void mda_speed_changed(void *p) -{ - mda_t *mda = (mda_t *)p; - - mda_recalctimings(mda); -} - -static const device_config_t mda_config[] = -{ - { - "rgb_type", "Display type", CONFIG_SELECTION, "", 0, - { - { - "Default", 0 - }, - { - "Green", 1 - }, - { - "Amber", 2 - }, - { - "Gray", 3 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t mda_device = -{ - "MDA", - DEVICE_ISA, 0, - mda_init, mda_close, NULL, - NULL, - mda_speed_changed, - NULL, - mda_config -}; diff --git a/backup code/video - Cópia/vid_mda.h b/backup code/video - Cópia/vid_mda.h deleted file mode 100644 index 4e1e78e41..000000000 --- a/backup code/video - Cópia/vid_mda.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t mda_device; diff --git a/backup code/video - Cópia/vid_nv_riva128.c b/backup code/video - Cópia/vid_nv_riva128.c deleted file mode 100644 index a74569153..000000000 --- a/backup code/video - Cópia/vid_nv_riva128.c +++ /dev/null @@ -1,3711 +0,0 @@ -/* - * 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. - * - * nVidia RIVA 128 emulation. - * - * Version: @(#)vid_nv_riva128.c 1.0.7 2018/04/29 - * - * Author: Melissa Goad - * Miran Grca, - * - * Copyright 2015-2018 Melissa Goad. - * Copyright 2015-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../pic.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../plat.h" -#include "video.h" -#include "vid_nv_riva128.h" -#include "vid_svga.h" -#include "vid_svga_render.h" - - -typedef struct riva128_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t ramin_mapping; - mem_mapping_t mmio_mapping; - - rom_t bios_rom; - - svga_t svga; - - uint8_t card_id; - int pci_card; - int is_nv3t; - - uint16_t vendor_id; - uint16_t device_id; - - uint32_t linear_base, linear_size; - - uint16_t rma_addr; - - uint8_t pci_regs[256]; - - int memory_size; - - uint8_t ext_regs_locked; - - uint8_t read_bank; - uint8_t write_bank; - - struct - { - uint32_t intr; - uint32_t intr_en; - uint32_t intr_line; - uint32_t enable; - } pmc; - - struct - { - uint32_t intr; - uint32_t intr_en; - } pbus; - - struct - { - uint32_t cache_error; - uint32_t intr; - uint32_t intr_en; - - uint32_t ramht; - uint32_t ramht_addr; - uint32_t ramht_size; - - uint32_t ramfc; - uint32_t ramfc_addr; - - uint32_t ramro; - uint32_t ramro_addr; - uint32_t ramro_size; - - uint16_t chan_mode; - uint16_t chan_dma; - uint16_t chan_size; //0 = 1024, 1 = 512 - - uint32_t runout_put, runout_get; - - struct - { - uint32_t dmaput; - uint32_t dmaget; - } channels[16]; - - struct - { - int chanid; - int push_enabled; - int runout; - uint32_t get, put; - uint32_t ctx; - } caches[2]; - - struct - { - int subchan; - uint16_t method; - uint32_t param; - } cache0, cache1[64]; - } pfifo; - - struct - { - uint32_t addr; - uint32_t data; - uint8_t access_reg[4]; - uint8_t mode; - } rma; - - struct - { - uint32_t intr, intr_en; - - uint64_t time; - uint32_t alarm; - - uint16_t clock_mul, clock_div; - } ptimer; - - struct - { - int width; - int bpp; - uint32_t config_0; - } pfb; - - struct - { - uint32_t boot_0; - } pextdev; - - struct - { - int pgraph_speedhack; - - uint32_t obj_handle[8]; - uint16_t obj_class[8]; - - uint32_t debug[5]; - - uint32_t intr; - uint32_t intr_en; - - uint32_t invalid; - uint32_t invalid_en; - - uint32_t ctx_switch[5]; - uint32_t ctx_control; - uint32_t ctx_user; - uint32_t ctx_cache[8][5]; - - uint32_t fifo_enable; - - uint32_t fifo_st2_addr; - uint32_t fifo_st2_data; - - uint32_t uclip_xmin, uclip_ymin, uclip_xmax, uclip_ymax; - uint32_t oclip_xmin, oclip_ymin, oclip_xmax, oclip_ymax; - - uint32_t src_canvas_min, src_canvas_max; - uint32_t dst_canvas_min, dst_canvas_max; - - uint8_t rop; - - uint32_t chroma; - - uint32_t beta; - - uint32_t notify; - - //NV4+ - uint32_t surf_base[6]; - uint32_t surf_limit[6]; - - //NV3 - uint32_t surf_offset[4]; - uint32_t surf_pitch[4]; - - uint32_t cliprect_min[2]; - uint32_t cliprect_max[2]; - uint32_t cliprect_ctrl; - - uint32_t instance; - - uint32_t dma_intr, dma_intr_en; - - uint32_t status; - - struct - { - uint32_t point_color; - int32_t point_x[0x20], point_y[0x20]; - } speedhack; - } pgraph; - - struct - { - uint32_t nvpll; - uint32_t nv_m,nv_n,nv_p; - - uint32_t mpll; - uint32_t m_m,m_n,m_p; - - uint32_t vpll; - uint32_t v_m,v_n,v_p; - - uint32_t pll_ctrl; - - uint32_t gen_ctrl; - } pramdac; - - uint32_t pramin[0x80000]; - - uint32_t channels[16][8][0x2000]; - - struct - { - int scl; - int sda; - enum - { - I2C_START, I2C_STOP, I2C_WAITACK, I2C_READ, I2C_WRITE - } state; - unsigned addrbits; - unsigned databits; - uint8_t addr; //actually 7 bits - uint8_t data; - struct - { - uint8_t addr; //actually 7 bits - uint8_t edid_rom[128]; - } edid_rom; - } i2c; - - int64_t mtime, mfreq; - int64_t nvtime, nvfreq; - int64_t menable; - int64_t nvenable; -} riva128_t; - -//Internally, the RIVA 128 operates in a weird 38-bit color depth, with 10 bits for RGB, and 8 bits for alpha, according to envytools. -typedef struct -{ - uint8_t a; - unsigned r : 10; - unsigned g : 10; - unsigned b : 10; -} riva128_color_t; - -const char* riva128_pmc_interrupts[32] = -{ - "","","","","PMEDIA","","","","PFIFO","","","","PGRAPH","","","","PRAMDAC.VIDEO","","","","PTIMER","","","","PCRTC","","","","PBUS","","","" -}; - -const char* riva128_pbus_interrupts[32] = -{ - "BUS_ERROR","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","" -}; - -const char* riva128_pfifo_interrupts[32] = -{ - "CACHE_ERROR","","","","RUNOUT","","","","RUNOUT_OVERFLOW","","","","DMA_PUSHER","","","","DMA_PTE","","","","","","","","","","","","","","","" -}; - - uint32_t riva128_ramht_lookup(uint32_t handle, void *p); -// void riva128_pgraph_volatile_reset(void *p); - - uint8_t riva128_pci_read(int func, int addr, void *p); - void riva128_pci_write(int func, int addr, uint8_t val, void *p); - - uint8_t riva128_in(uint16_t addr, void *p); - void riva128_out(uint16_t addr, uint8_t val, void *p); - - void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p); - -#ifdef ENABLE_NV_RIVA_LOG -int nv_riva_do_log = ENABLE_NV_RIVA_LOG; -#endif - - -static void -nv_riva_log(const char *fmt, ...) -{ -#ifdef ENABLE_NV_RIVA_LOG - va_list ap; - - if (nv_riva_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -/* riva128_color_t riva128_pgraph_expand_color(uint32_t ctx, uint32_t color) -{ - riva128_color_t ret; - int format = ctx & 7; - int alpha_enable = (ctx >> 3) & 1; - - switch(format) - { - default: - nv_riva_log("RIVA 128 Unknown color format %i found!\n", format); - ret.a = 0x0; - break; - case 0: - ret.a = ((color >> 15) & 1) * 0xff; - ret.r = ((color >> 10) & 0x1f) << 5; - ret.g = ((color >> 5) & 0x1f) << 5; - ret.b = ((color >> 0) & 0x1f) << 5; - break; - case 1: - ret.a = ((color >> 24) & 0xff); - ret.r = ((color >> 16) & 0xff) << 2; - ret.g = ((color >> 8) & 0xff) << 2; - ret.b = ((color >> 0) & 0xff) << 2; - break; - case 2: - ret.a = ((color >> 30) & 3) * 0x55; - ret.r = ((color >> 20) & 0x3ff); - ret.g = ((color >> 10) & 0x3ff); - ret.b = ((color >> 0) & 0x3ff); - break; - case 3: - ret.a = ((color >> 8) & 0xff); - ret.r = ret.g = ret.b = ((color >> 0) & 0xff) << 2; - break; - case 4: - ret.a = ((color >> 16) & 0xffff) >> 8; - ret.r = ret.g = ret.b = ((color >> 0) & 0xffff) >> 6; - break; - } - - if(!alpha_enable) ret.a = 0xff; - - return ret; -} - - uint32_t riva128_pgraph_blend_factor(uint32_t alpha, uint32_t beta) -{ - if(beta == 0xff) return alpha; - if(alpha == 0xff) return beta; - alpha >>= 4; - beta >>= 3; - return (alpha * beta) >> 1; -} - - uint32_t riva128_pgraph_do_blend(uint32_t factor, uint32_t dst, uint32_t src, int is_r5g5b5) -{ - factor &= 0xf8; - if(factor == 0xf8) return src; - if(!factor) return dst; - src >>= 2; - dst >>= 2; - if(is_r5g5b5) - { - src &= 0xf8; - dst &= 0xf8; - } - return ((dst * (0x100 - factor)) + (src * factor)) >> 6; -}*/ - - uint8_t riva128_pmc_read(uint32_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint8_t ret = 0; - - //nv_riva_log("RIVA 128 PMC read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - - if(riva128->card_id == 0x03) switch(addr) - { - case 0x000000: - ret = 0x00; - break; - case 0x000001: - ret = 0x01; - break; - case 0x000002: - ret = 0x03; - break; - case 0x000003: - ret = 0x00; - break; - } - else if(riva128->card_id == 0x04) switch(addr) - { - case 0x000000: - ret = 0x00; - break; - case 0x000001: - ret = 0x40; - break; - case 0x000002: - ret = 0x00; - break; - case 0x000003: - ret = 0x00; - break; - } - else if(riva128->card_id == 0x05) switch(addr) - { - case 0x000000: - ret = 0x00; - break; - case 0x000001: - ret = 0x40; - break; - case 0x000002: - ret = 0x10; - break; - case 0x000003: - ret = 0x00; - break; - } - switch(addr) - { - case 0x000100: - ret = riva128->pmc.intr & 0xff; - break; - case 0x000101: - ret = (riva128->pmc.intr >> 8) & 0xff; - break; - case 0x000102: - ret = (riva128->pmc.intr >> 16) & 0xff; - break; - case 0x000103: - ret = (riva128->pmc.intr >> 24) & 0xff; - break; - case 0x000140: - ret = riva128->pmc.intr & 0xff; - break; - case 0x000141: - ret = (riva128->pmc.intr_en >> 8) & 0xff; - break; - case 0x000142: - ret = (riva128->pmc.intr_en >> 16) & 0xff; - break; - case 0x000143: - ret = (riva128->pmc.intr_en >> 24) & 0xff; - break; - case 0x000160: - ret = riva128->pmc.intr_line & 0xff; - break; - case 0x000161: - ret = (riva128->pmc.intr_line >> 8) & 0xff; - break; - case 0x000162: - ret = (riva128->pmc.intr_line >> 16) & 0xff; - break; - case 0x000163: - ret = (riva128->pmc.intr_line >> 24) & 0xff; - break; - case 0x000200: - ret = riva128->pmc.enable & 0xff; - break; - case 0x000201: - ret = (riva128->pmc.enable >> 8) & 0xff; - break; - case 0x000202: - ret = (riva128->pmc.enable >> 16) & 0xff; - break; - case 0x000203: - ret = (riva128->pmc.enable >> 24) & 0xff; - break; - } - - return ret; -} - - void riva128_pmc_write(uint32_t addr, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - //nv_riva_log("RIVA 128 PMC write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - - switch(addr) - { - case 0x000100: - { - uint32_t tmp = riva128->pmc.intr & ~val; - pci_clear_irq(riva128->pci_card, PCI_INTA); - riva128->pmc.intr = tmp; - break; - } - case 0x000140: - riva128->pmc.intr_en = val & 3; - break; - case 0x000200: - riva128->pmc.enable = val; - break; - } -} - - void riva128_pmc_interrupt(int num, void *p) -{ - //nv_riva_log("RIVA 128 PMC interrupt #%d fired!\n", num); - riva128_t *riva128 = (riva128_t *)p; - - riva128->pmc.intr |= (1 << num); - - if(riva128->pmc.intr_en & 1) - { - pci_set_irq(riva128->pci_card, PCI_INTA); - } -} - - uint8_t riva128_pbus_read(uint32_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint8_t ret = 0; - - //nv_riva_log("RIVA 128 PBUS read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - - switch(addr) - { - case 0x001100: - ret = riva128->pbus.intr & 0xff; - break; - case 0x001101: - ret = (riva128->pbus.intr >> 8) & 0xff; - break; - case 0x001102: - ret = (riva128->pbus.intr >> 16) & 0xff; - break; - case 0x001103: - ret = (riva128->pbus.intr >> 24) & 0xff; - break; - case 0x001140: - ret = riva128->pbus.intr & 0xff; - break; - case 0x001141: - ret = (riva128->pbus.intr_en >> 8) & 0xff; - break; - case 0x001142: - ret = (riva128->pbus.intr_en >> 16) & 0xff; - break; - case 0x001143: - ret = (riva128->pbus.intr_en >> 24) & 0xff; - break; - } - - if((addr >= 0x001800) && (addr <= 0x0018ff)) ret = riva128_pci_read(0, addr - 0x1800, riva128); - - return ret; -} - - void riva128_pbus_write(uint32_t addr, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - //nv_riva_log("RIVA 128 PBUS write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - - switch(addr) - { - case 0x001100: - riva128->pbus.intr &= ~val; - break; - case 0x001140: - riva128->pbus.intr_en = val; - break; - } - - if((addr >= 0x001800) && (addr <= 0x0018ff)) - { - riva128_pci_write(0, (addr & 0xfc) + 0, (val >> 0) & 0xff, riva128); - riva128_pci_write(0, (addr & 0xfc) + 1, (val >> 8) & 0xff, riva128); - riva128_pci_write(0, (addr & 0xfc) + 2, (val >> 16) & 0xff, riva128); - riva128_pci_write(0, (addr & 0xfc) + 3, (val >> 24) & 0xff, riva128); - } -} - -void riva128_pfifo_interrupt(int num, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - riva128->pfifo.intr |= (1 << num); - - if(num == 0) riva128->pfifo.cache_error = 0x11; - - riva128_pmc_interrupt(8, riva128); -} - -uint32_t riva128_pfifo_runout_next(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint32_t next = (riva128->pfifo.runout_put + 8) & ((riva128->pfifo.ramro_size) - 1); - return next; -} - -uint32_t riva128_pfifo_cache1_next(uint32_t ptr) -{ - //Apparently, PFIFO's CACHE1 uses some sort of Gray code... oh well - int bits = 5; - uint32_t tmp = ptr >> 2; - if(tmp == (1 << (bits - 1))) return 0; - for(int bit = bits - 1;bit > 0;bit--) - { - if(tmp == (1 << (bit - 1))) return ptr ^ (1 << (2 + bit)); - if(tmp & (1 << bit)) tmp ^= 3 << (bit - 1); - } - return ptr ^ 4; -} - -uint32_t riva128_pfifo_cache1_lin(uint32_t ptr) -{ - int bits = 5; - uint32_t res = 0; - uint32_t tmp = ptr >> 2; - for(int bit = bits = 1; bit > 0; bit--) - { - if(tmp & (1 << bit)) - { - tmp ^= 3 << (bit - 1); - res ^= 4 << bit; - } - } - if(tmp & 1) res ^= 4; - return res; -} - -uint32_t riva128_pfifo_cache1_free(uint32_t chid, void* p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint32_t get = riva128_pfifo_cache1_lin(riva128->pfifo.caches[1].get); - uint32_t put = riva128_pfifo_cache1_lin(riva128->pfifo.caches[1].put); - - if(riva128->pfifo.caches[1].runout) return 0; - if(chid != riva128->pfifo.caches[1].chanid || !riva128->pfifo.caches[1].push_enabled) - { - if(riva128->pfifo.caches[1].get != riva128->pfifo.caches[1].put) return 0; - return 0x7c; - } - return (get - put - 4) & 0x7c; -} - - uint8_t riva128_pfifo_read(uint32_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint8_t ret = 0; - - // nv_riva_log("RIVA 128 PFIFO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - - switch(addr) - { - case 0x002080: - ret = riva128->pfifo.cache_error & 0xff; - break; - case 0x002081: - ret = (riva128->pfifo.cache_error >> 8) & 0xff; - break; - case 0x002082: - ret = (riva128->pfifo.cache_error >> 16) & 0xff; - break; - case 0x002083: - ret = (riva128->pfifo.cache_error >> 24) & 0xff; - break; - case 0x002100: - ret = riva128->pfifo.intr & 0xff; - break; - case 0x002101: - ret = (riva128->pfifo.intr >> 8) & 0xff; - break; - case 0x002102: - ret = (riva128->pfifo.intr >> 16) & 0xff; - break; - case 0x002103: - ret = (riva128->pfifo.intr >> 24) & 0xff; - break; - case 0x002140: - ret = riva128->pfifo.intr_en & 0xff; - break; - case 0x002141: - ret = (riva128->pfifo.intr_en >> 8) & 0xff; - break; - case 0x002142: - ret = (riva128->pfifo.intr_en >> 16) & 0xff; - break; - case 0x002143: - ret = (riva128->pfifo.intr_en >> 24) & 0xff; - break; - case 0x002210: - ret = riva128->pfifo.ramht & 0xff; - break; - case 0x002211: - ret = (riva128->pfifo.ramht >> 8) & 0xff; - break; - case 0x002212: - ret = (riva128->pfifo.ramht >> 16) & 0xff; - break; - case 0x002213: - ret = (riva128->pfifo.ramht >> 24) & 0xff; - break; - case 0x002214: - ret = riva128->pfifo.ramfc & 0xff; - break; - case 0x002215: - ret = (riva128->pfifo.ramfc >> 8) & 0xff; - break; - case 0x002216: - ret = (riva128->pfifo.ramfc >> 16) & 0xff; - break; - case 0x002217: - ret = (riva128->pfifo.ramfc >> 24) & 0xff; - break; - case 0x002218: - ret = riva128->pfifo.ramro & 0xff; - break; - case 0x002219: - ret = (riva128->pfifo.ramro >> 8) & 0xff; - break; - case 0x00221a: - ret = (riva128->pfifo.ramro >> 16) & 0xff; - break; - case 0x00221b: - ret = (riva128->pfifo.ramro >> 24) & 0xff; - break; - case 0x002504: - ret = riva128->pfifo.chan_mode & 0xff; - break; - case 0x002505: - ret = (riva128->pfifo.chan_mode >> 8) & 0xff; - break; - case 0x002506: - ret = (riva128->pfifo.chan_mode >> 16) & 0xff; - break; - case 0x002507: - ret = (riva128->pfifo.chan_mode >> 24) & 0xff; - break; - case 0x002508: - ret = riva128->pfifo.chan_dma & 0xff; - break; - case 0x002509: - ret = (riva128->pfifo.chan_dma >> 8) & 0xff; - break; - case 0x00250a: - ret = (riva128->pfifo.chan_dma >> 16) & 0xff; - break; - case 0x00250b: - ret = (riva128->pfifo.chan_dma >> 24) & 0xff; - break; - case 0x00250c: - ret = riva128->pfifo.chan_size & 0xff; - break; - case 0x00250d: - ret = (riva128->pfifo.chan_size >> 8) & 0xff; - break; - case 0x00250e: - ret = (riva128->pfifo.chan_size >> 16) & 0xff; - break; - case 0x00250f: - ret = (riva128->pfifo.chan_size >> 24) & 0xff; - break; - //HACK - case 0x002400: - ret = 0x10; - break; - case 0x002401: - ret = 0x00; - break; - case 0x003204: - ret = riva128->pfifo.caches[1].chanid; - break; - case 0x003214: - ret = 0x10; - break; - case 0x003215: - ret = 0x00; - break; - case 0x003220: - ret = 0x01; - break; - } - - return ret; -} - - void riva128_pfifo_write(uint32_t addr, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - // nv_riva_log("RIVA 128 PFIFO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - - switch(addr) - { - case 0x002100: - riva128->pfifo.intr &= ~val; - break; - case 0x002140: - riva128->pfifo.intr_en = val; - break; - case 0x002210: - riva128->pfifo.ramht = val; - riva128->pfifo.ramht_addr = (val & 0x1f0) << 8; - switch(val & 0x30000) - { - case 0x00000: - riva128->pfifo.ramht_size = 4 * 1024; - break; - case 0x10000: - riva128->pfifo.ramht_size = 8 * 1024; - break; - case 0x20000: - riva128->pfifo.ramht_size = 16 * 1024; - break; - case 0x30000: - riva128->pfifo.ramht_size = 32 * 1024; - break; - } - break; - case 0x002214: - riva128->pfifo.ramfc = val; - riva128->pfifo.ramfc_addr = (val & 0x1fe) << 4; - break; - case 0x002218: - riva128->pfifo.ramro = val; - riva128->pfifo.ramro_addr = (val & 0x1fe) << 4; - if(val & 0x10000) riva128->pfifo.ramro_size = 8192; - else riva128->pfifo.ramro_size = 512; - break; - case 0x002504: - riva128->pfifo.chan_mode = val; - break; - case 0x002508: - riva128->pfifo.chan_dma = val; - break; - case 0x00250c: - riva128->pfifo.chan_size = val; - break; - case 0x003200: - riva128->pfifo.caches[1].push_enabled = val; - break; - case 0x003204: - riva128->pfifo.caches[1].chanid = val; - break; - //HACKS - case 0x002500: - riva128_pfifo_interrupt(0, riva128); - break; - } -} - - uint8_t riva128_ptimer_read(uint32_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint8_t ret = 0; - - //nv_riva_log("RIVA 128 PTIMER read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - - switch(addr) - { - case 0x009100: - ret = riva128->ptimer.intr & 0xff; - break; - case 0x009101: - ret = (riva128->ptimer.intr >> 8) & 0xff; - break; - case 0x009102: - ret = (riva128->ptimer.intr >> 16) & 0xff; - break; - case 0x009103: - ret = (riva128->ptimer.intr >> 24) & 0xff; - break; - case 0x009140: - ret = riva128->ptimer.intr & 0xff; - break; - case 0x009141: - ret = (riva128->ptimer.intr_en >> 8) & 0xff; - break; - case 0x009142: - ret = (riva128->ptimer.intr_en >> 16) & 0xff; - break; - case 0x009143: - ret = (riva128->ptimer.intr_en >> 24) & 0xff; - break; - case 0x009200: - ret = riva128->ptimer.clock_div & 0xff; - break; - case 0x009201: - ret = (riva128->ptimer.clock_div >> 8) & 0xff; - break; - case 0x009202: - ret = (riva128->ptimer.clock_div >> 16) & 0xff; - break; - case 0x009203: - ret = (riva128->ptimer.clock_div >> 24) & 0xff; - break; - case 0x009210: - ret = riva128->ptimer.clock_mul & 0xff; - break; - case 0x009211: - ret = (riva128->ptimer.clock_mul >> 8) & 0xff; - break; - case 0x009212: - ret = (riva128->ptimer.clock_mul >> 16) & 0xff; - break; - case 0x009213: - ret = (riva128->ptimer.clock_mul >> 24) & 0xff; - break; - case 0x009400: - ret = riva128->ptimer.time & 0xff; - break; - case 0x009401: - ret = (riva128->ptimer.time >> 8) & 0xff; - break; - case 0x009402: - ret = (riva128->ptimer.time >> 16) & 0xff; - break; - case 0x009403: - ret = (riva128->ptimer.time >> 24) & 0xff; - break; - case 0x009410: - ret = (riva128->ptimer.time >> 32) & 0xff; - break; - case 0x009411: - ret = (riva128->ptimer.time >> 40) & 0xff; - break; - case 0x009412: - ret = (riva128->ptimer.time >> 48) & 0xff; - break; - case 0x009413: - ret = (riva128->ptimer.time >> 56) & 0xff; - break; - case 0x009420: - ret = riva128->ptimer.alarm & 0xff; - break; - case 0x009421: - ret = (riva128->ptimer.alarm >> 8) & 0xff; - break; - case 0x009422: - ret = (riva128->ptimer.alarm >> 16) & 0xff; - break; - case 0x009423: - ret = (riva128->ptimer.alarm >> 24) & 0xff; - break; - } - - - //riva128->ptimer.time += 0x10000; - - return ret; -} - - void riva128_ptimer_write(uint32_t addr, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - nv_riva_log("RIVA 128 PTIMER write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - - switch(addr) - { - case 0x009100: - riva128->ptimer.intr &= ~val; - break; - case 0x009140: - riva128->ptimer.intr_en = val; - break; - case 0x009200: - if(!(val & 0xffff)) val = 1; - riva128->ptimer.clock_div = val & 0xffff; - break; - case 0x009210: - if((val & 0xffff) < riva128->ptimer.clock_div) val = riva128->ptimer.clock_div; - riva128->ptimer.clock_mul = val & 0xffff; - break; - case 0x009400: - riva128->ptimer.time &= 0x0fffffff00000000ULL; - riva128->ptimer.time |= val & 0xffffffe0; - break; - case 0x009410: - riva128->ptimer.time &= 0xffffffe0; - riva128->ptimer.time |= val & 0x0fffffff00000000ULL; - break; - case 0x009420: - riva128->ptimer.alarm = val & 0xffffffe0; - break; - } -} - - void riva128_ptimer_interrupt(int num, void *p) -{ - //nv_riva_log("RIVA 128 PTIMER interrupt #%d fired!\n", num); - riva128_t *riva128 = (riva128_t *)p; - - riva128->ptimer.intr |= (1 << num); - - riva128_pmc_interrupt(20, riva128); -} - - uint8_t riva128_pfb_read(uint32_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint8_t ret = 0; - - //nv_riva_log("RIVA 128 PFB read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - - switch(addr) - { - case 0x100000: - { - switch(riva128->card_id) - { - case 0x03: - { - switch(riva128->memory_size) - { - case 1: - case 8: - ret = 0; - case 2: - ret = 1; - case 4: - ret = 2; - } - ret |= 0x0c; - break; - } - case 0x04: - case 0x05: - { - switch(riva128->memory_size) - { - case 4: - ret = 1; - break; - case 8: - ret = 2; - break; - case 16: - ret = 3; - break; - case 32: - ret = 0; - break; - } - ret |= 0x14; - break; - } - } - break; - } - case 0x100200: - ret = riva128->pfb.config_0 & 0xff; - break; - case 0x100201: - ret = (riva128->pfb.config_0 >> 8) & 0xff; - break; - case 0x100202: - ret = (riva128->pfb.config_0 >> 16) & 0xff; - break; - case 0x100203: - ret = (riva128->pfb.config_0 >> 24) & 0xff; - break; - } - - return ret; -} - - void riva128_pfb_write(uint32_t addr, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - //nv_riva_log("RIVA 128 PFB write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - - switch(addr) - { - case 0x100200: - riva128->pfb.config_0 = (val & 0x33f) | 0x1000; - riva128->pfb.width = (val & 0x3f) << 5; - switch((val >> 8) & 3) - { - case 1: - riva128->pfb.bpp = 8; - break; - case 2: - riva128->pfb.bpp = 16; - break; - case 3: - riva128->pfb.bpp = 32; - break; - } - break; - } -} - -uint8_t riva128_pextdev_read(uint32_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint8_t ret = 0; - - //nv_riva_log("RIVA 128 PEXTDEV read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - - //For NV3, we give it PCI 66MHz, card mode, PCI bus type, 13.5MHz crystal, no TV encoder, and PCI 2.1. - //For NV4, we give it normal PCI line polarity, card mode, 13.5 MHz crystal, no TV encoder, and PCI bus type - - switch(addr) - { - case 0x101000: - switch(riva128->card_id) - { - case 0x03: - ret = 0x13; - break; - case 0x04: - ret = 0x83; - break; - } - break; - case 0x101001: - switch(riva128->card_id) - { - case 0x03: - if(!riva128->is_nv3t) ret = 0x02; - else ret = 0x00; - break; - case 0x04: case 0x05: - //Bits 12-13 of the NV4+ strap set 0 configure the GPU's PCI device ID. - ret = (riva128->pextdev.boot_0 & 0x80000000) ? (0x8f | ((riva128->pextdev.boot_0 >> 8) & 0x30)) : 0x8f; - break; - break; - } - } - - return ret; -} - -void riva128_pextdev_write(uint32_t addr, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - //nv_riva_log("RIVA 128 PEXTDEV write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - - switch(addr) - { - case 0x101000: - riva128->pextdev.boot_0 = val; - if((val & 0x80000000) && ((riva128->card_id == 0x05) || (riva128->card_id == 0x10) || (riva128->card_id == 0x11) || (riva128->card_id == 0x15) - || (riva128->card_id == 0x1a))) - { - riva128->device_id = (riva128->device_id & 0xfffc) | ((val >> 12) & 3); - } - break; - } -} - -void rivatnt_pgraph_ctx_switch(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - unsigned old_subc = (riva128->pgraph.ctx_user >> 13) & 7; - unsigned new_subc = (riva128->pgraph.fifo_st2_addr >> 12) & 7; - unsigned mthd = (riva128->pgraph.fifo_st2_addr >> 1) & 0x7ff; - unsigned do_ctx_switch = mthd == 0; - - if(!(riva128->pgraph.fifo_st2_addr & 1)) return; - riva128->pgraph.fifo_st2_addr &= ~1; - - if(old_subc != new_subc || do_ctx_switch) - { - uint32_t ctx_mask = 0x0303f0ff; - - unsigned reload = (riva128->pgraph.debug[1] >> 15) & 1; - - unsigned reset = (riva128->pgraph.debug[2] >> 28) & 1; - - if(do_ctx_switch) riva128->pgraph.ctx_cache[new_subc][3] = riva128->pgraph.fifo_st2_data & 0xffff; - - if(reload || do_ctx_switch) - { - uint32_t instance = riva128_ramht_lookup(riva128->pgraph.fifo_st2_data, riva128); - riva128->pgraph.ctx_cache[new_subc][0] = riva128->pramin[(instance >> 2)] & ctx_mask; - riva128->pgraph.ctx_cache[new_subc][1] = riva128->pramin[(instance >> 2) + 1] & 0xffff3f03; - riva128->pgraph.ctx_cache[new_subc][2] = riva128->pramin[(instance >> 2) + 2]; - riva128->pgraph.ctx_cache[new_subc][4] = riva128->pramin[(instance >> 2) + 3]; - } - - if(reset) - { - riva128->pgraph.debug[1] |= 1; - //riva128_pgraph_volatile_reset(riva128); - } - else riva128->pgraph.debug[1] &= ~1; - - if(riva128->pgraph.debug[1] & 0x100000) - { - int i; - for(i = 0; i < 5; i++) riva128->pgraph.ctx_switch[i] = riva128->pgraph.ctx_cache[new_subc][i]; - } - } -} - - uint8_t riva128_pgraph_read(uint32_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint8_t ret = 0; - - nv_riva_log("RIVA 128 PGRAPH read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - - switch(addr) - { - case 0x400080: - ret = riva128->pgraph.debug[0] & 0xff; - break; - case 0x400081: - ret = (riva128->pgraph.debug[0] >> 8) & 0xff; - break; - case 0x400082: - ret = (riva128->pgraph.debug[0] >> 16) & 0xff; - break; - case 0x400083: - ret = (riva128->pgraph.debug[0] >> 24) & 0xff; - break; - case 0x400084: - ret = riva128->pgraph.debug[1] & 0xff; - break; - case 0x400085: - ret = (riva128->pgraph.debug[1] >> 8) & 0xff; - break; - case 0x400086: - ret = (riva128->pgraph.debug[1] >> 16) & 0xff; - break; - case 0x400087: - ret = (riva128->pgraph.debug[1] >> 24) & 0xff; - break; - case 0x400088: - ret = riva128->pgraph.debug[2] & 0xff; - break; - case 0x400089: - ret = (riva128->pgraph.debug[2] >> 8) & 0xff; - break; - case 0x40008a: - ret = (riva128->pgraph.debug[2] >> 16) & 0xff; - break; - case 0x40008b: - ret = (riva128->pgraph.debug[2] >> 24) & 0xff; - break; - case 0x40008c: - ret = riva128->pgraph.debug[3] & 0xff; - break; - case 0x40008d: - ret = (riva128->pgraph.debug[3] >> 8) & 0xff; - break; - case 0x40008e: - ret = (riva128->pgraph.debug[3] >> 16) & 0xff; - break; - case 0x40008f: - ret = (riva128->pgraph.debug[3] >> 24) & 0xff; - break; - - case 0x400100: - ret = riva128->pgraph.intr & 0xff; - break; - case 0x400101: - ret = (riva128->pgraph.intr >> 8) & 0xff; - break; - case 0x400102: - ret = (riva128->pgraph.intr >> 16) & 0xff; - break; - case 0x400103: - ret = (riva128->pgraph.intr >> 24) & 0xff; - break; - case 0x400104: - ret = riva128->pgraph.invalid & 0xff; - break; - case 0x400105: - ret = (riva128->pgraph.invalid >> 8) & 0xff; - break; - case 0x400106: - ret = (riva128->pgraph.invalid >> 16) & 0xff; - break; - case 0x400107: - ret = (riva128->pgraph.invalid >> 24) & 0xff; - break; - case 0x400140: - ret = riva128->pgraph.intr_en & 0xff; - break; - case 0x400141: - ret = (riva128->pgraph.intr_en >> 8) & 0xff; - break; - case 0x400142: - ret = (riva128->pgraph.intr_en >> 16) & 0xff; - break; - case 0x400143: - ret = (riva128->pgraph.intr_en >> 24) & 0xff; - break; - case 0x400144: - ret = riva128->pgraph.invalid_en & 0xff; - break; - case 0x400145: - ret = (riva128->pgraph.invalid_en >> 8) & 0xff; - break; - case 0x400146: - ret = (riva128->pgraph.invalid_en >> 16) & 0xff; - break; - case 0x400147: - ret = (riva128->pgraph.invalid_en >> 24) & 0xff; - break; - - case 0x400180: - ret = riva128->pgraph.ctx_switch[0] & 0xff; - break; - case 0x400181: - ret = (riva128->pgraph.ctx_switch[0] >> 8) & 0xff; - break; - case 0x400182: - ret = (riva128->pgraph.ctx_switch[0] >> 16) & 0xff; - break; - case 0x400183: - ret = (riva128->pgraph.ctx_switch[0] >> 24) & 0xff; - break; - - case 0x400190: - ret = riva128->pgraph.ctx_control & 0xff; - break; - case 0x400191: - ret = (riva128->pgraph.ctx_control >> 8) & 0xff; - break; - case 0x400192: - ret = (riva128->pgraph.ctx_control >> 16) & 0xff; - break; - case 0x400193: - ret = (riva128->pgraph.ctx_control >> 24) & 0xff; - break; - case 0x400194: - ret = riva128->pgraph.ctx_user & 0xff; - break; - case 0x400195: - ret = (riva128->pgraph.ctx_user >> 8) & 0xff; - break; - case 0x400196: - ret = (riva128->pgraph.ctx_user >> 16) & 0xff; - break; - case 0x400197: - ret = (riva128->pgraph.ctx_user >> 24) & 0xff; - break; - - case 0x4001a0: case 0x4001a1: case 0x4001a2: case 0x4001a3: case 0x4001a4: case 0x4001a5: case 0x4001a6: case 0x4001a7: - case 0x4001a8: case 0x4001a9: case 0x4001aa: case 0x4001ab: case 0x4001ac: case 0x4001ad: case 0x4001ae: case 0x4001af: - case 0x4001b0: case 0x4001b1: case 0x4001b2: case 0x4001b3: case 0x4001b4: case 0x4001b5: case 0x4001b6: case 0x4001b7: - case 0x4001b8: case 0x4001b9: case 0x4001ba: case 0x4001bb: case 0x4001bc: case 0x4001bd: case 0x4001be: case 0x4001bf: - ret = (riva128->pgraph.ctx_cache[(addr & 0x1c) >> 2][0] >> ((addr & 3) << 3)) & 0xff; - break; - - case 0x4006a4: - ret = riva128->pgraph.fifo_enable & 1; - break; - - case 0x4006b0: - ret = riva128->pgraph.status & 0xff; - break; - case 0x4006b1: - ret = (riva128->pgraph.status >> 8) & 0xff; - break; - case 0x4006b2: - ret = (riva128->pgraph.status >> 16) & 0xff; - break; - case 0x4006b3: - ret = (riva128->pgraph.status >> 24) & 0xff; - //HACK - riva128->pgraph.status ^= 0x1f131111; - break; - - case 0x401100: - ret = riva128->pgraph.dma_intr & 0xff; - break; - case 0x401101: - ret = (riva128->pgraph.dma_intr >> 8) & 0xff; - break; - case 0x401102: - ret = (riva128->pgraph.dma_intr >> 16) & 0xff; - break; - case 0x401103: - ret = (riva128->pgraph.dma_intr >> 24) & 0xff; - break; - case 0x401140: - ret = riva128->pgraph.dma_intr_en & 0xff; - break; - case 0x401141: - ret = (riva128->pgraph.dma_intr_en >> 8) & 0xff; - break; - case 0x401142: - ret = (riva128->pgraph.dma_intr_en >> 16) & 0xff; - break; - case 0x401143: - ret = (riva128->pgraph.dma_intr_en >> 24) & 0xff; - break; - } - - if(riva128->card_id == 0x03) switch(addr) - { - case 0x40053c: - ret = riva128->pgraph.uclip_xmin & 0xff; - break; - case 0x40053d: - ret = (riva128->pgraph.uclip_xmin >> 8) & 0xff; - break; - case 0x40053e: - ret = (riva128->pgraph.uclip_xmin >> 16) & 0xff; - break; - case 0x40053f: - ret = (riva128->pgraph.uclip_xmin >> 24) & 0xff; - break; - case 0x400540: - ret = riva128->pgraph.uclip_ymin & 0xff; - break; - case 0x400541: - ret = (riva128->pgraph.uclip_ymin >> 8) & 0xff; - break; - case 0x400542: - ret = (riva128->pgraph.uclip_ymin >> 16) & 0xff; - break; - case 0x400543: - ret = (riva128->pgraph.uclip_ymin >> 24) & 0xff; - break; - case 0x400544: - ret = riva128->pgraph.uclip_xmax & 0xff; - break; - case 0x400545: - ret = (riva128->pgraph.uclip_xmax >> 8) & 0xff; - break; - case 0x400546: - ret = (riva128->pgraph.uclip_xmax >> 16) & 0xff; - break; - case 0x400547: - ret = (riva128->pgraph.uclip_xmax >> 24) & 0xff; - break; - case 0x400548: - ret = riva128->pgraph.uclip_ymax & 0xff; - break; - case 0x400549: - ret = (riva128->pgraph.uclip_ymax >> 8) & 0xff; - break; - case 0x40054a: - ret = (riva128->pgraph.uclip_ymax >> 16) & 0xff; - break; - case 0x40054b: - ret = (riva128->pgraph.uclip_ymax >> 24) & 0xff; - break; - case 0x400560: - ret = riva128->pgraph.oclip_xmin & 0xff; - break; - case 0x400561: - ret = (riva128->pgraph.oclip_xmin >> 8) & 0xff; - break; - case 0x400562: - ret = (riva128->pgraph.oclip_xmin >> 16) & 0xff; - break; - case 0x400563: - ret = (riva128->pgraph.oclip_xmin >> 24) & 0xff; - break; - case 0x400564: - ret = riva128->pgraph.oclip_ymin & 0xff; - break; - case 0x400565: - ret = (riva128->pgraph.oclip_ymin >> 8) & 0xff; - break; - case 0x400566: - ret = (riva128->pgraph.oclip_ymin >> 16) & 0xff; - break; - case 0x400567: - ret = (riva128->pgraph.oclip_ymin >> 24) & 0xff; - break; - case 0x400568: - ret = riva128->pgraph.oclip_xmax & 0xff; - break; - case 0x400569: - ret = (riva128->pgraph.oclip_xmax >> 8) & 0xff; - break; - case 0x40056a: - ret = (riva128->pgraph.oclip_xmax >> 16) & 0xff; - break; - case 0x40056b: - ret = (riva128->pgraph.oclip_xmax >> 24) & 0xff; - break; - case 0x40056c: - ret = riva128->pgraph.oclip_ymax & 0xff; - break; - case 0x40056d: - ret = (riva128->pgraph.oclip_ymax >> 8) & 0xff; - break; - case 0x40056e: - ret = (riva128->pgraph.oclip_ymax >> 16) & 0xff; - break; - case 0x40056f: - ret = (riva128->pgraph.oclip_ymax >> 24) & 0xff; - break; - case 0x400624: - ret = riva128->pgraph.rop; - break; - case 0x40062c: - ret = riva128->pgraph.beta & 0xff; - break; - case 0x40062d: - ret = (riva128->pgraph.beta >> 8) & 0xff; - break; - case 0x40062e: - ret = (riva128->pgraph.beta >> 16) & 0xff; - break; - case 0x40062f: - ret = (riva128->pgraph.beta >> 24) & 0xff; - break; - case 0x400640: - ret = riva128->pgraph.beta & 0xff; - break; - case 0x400641: - ret = (riva128->pgraph.beta >> 8) & 0xff; - break; - case 0x400642: - ret = (riva128->pgraph.beta >> 16) & 0xff; - break; - case 0x400643: - ret = (riva128->pgraph.beta >> 24) & 0xff; - break; - case 0x400684: - ret = riva128->pgraph.notify & 0xff; - break; - case 0x400685: - ret = (riva128->pgraph.notify >> 8) & 0xff; - break; - case 0x400686: - ret = (riva128->pgraph.notify >> 16) & 0xff; - break; - case 0x400687: - ret = (riva128->pgraph.notify >> 24) & 0xff; - break; - case 0x400690: - ret = riva128->pgraph.cliprect_min[0] & 0xff; - break; - case 0x400691: - ret = (riva128->pgraph.cliprect_min[0] >> 8) & 0xff; - break; - case 0x400692: - ret = (riva128->pgraph.cliprect_min[0] >> 16) & 0xff; - break; - case 0x400693: - ret = (riva128->pgraph.cliprect_min[0] >> 24) & 0xff; - break; - case 0x400694: - ret = riva128->pgraph.cliprect_max[0] & 0xff; - break; - case 0x400695: - ret = (riva128->pgraph.cliprect_max[0] >> 8) & 0xff; - break; - case 0x400696: - ret = (riva128->pgraph.cliprect_max[0] >> 16) & 0xff; - break; - case 0x400697: - ret = (riva128->pgraph.cliprect_max[0] >> 24) & 0xff; - break; - case 0x400698: - ret = riva128->pgraph.cliprect_min[1] & 0xff; - break; - case 0x400699: - ret = (riva128->pgraph.cliprect_min[1] >> 8) & 0xff; - break; - case 0x40069a: - ret = (riva128->pgraph.cliprect_min[1] >> 16) & 0xff; - break; - case 0x40069b: - ret = (riva128->pgraph.cliprect_min[1] >> 24) & 0xff; - break; - case 0x40069c: - ret = riva128->pgraph.cliprect_max[1] & 0xff; - break; - case 0x40069d: - ret = (riva128->pgraph.cliprect_max[1] >> 8) & 0xff; - break; - case 0x40069e: - ret = (riva128->pgraph.cliprect_max[1] >> 16) & 0xff; - break; - case 0x40069f: - ret = (riva128->pgraph.cliprect_max[1] >> 24) & 0xff; - break; - case 0x4006a0: - ret = riva128->pgraph.cliprect_ctrl & 0xff; - break; - case 0x4006a1: - ret = (riva128->pgraph.cliprect_ctrl >> 8) & 0xff; - break; - case 0x4006a2: - ret = (riva128->pgraph.cliprect_ctrl >> 16) & 0xff; - break; - case 0x4006a3: - ret = (riva128->pgraph.cliprect_ctrl >> 24) & 0xff; - break; - } - - return ret; -} - - void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - nv_riva_log("RIVA 128 PGRAPH write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - - switch(addr) - { - case 0x400100: - riva128->pgraph.intr &= ~val; - break; - case 0x400104: - riva128->pgraph.invalid &= ~val; - break; - case 0x400140: - riva128->pgraph.intr_en = val; - if(riva128->card_id == 0x03) riva128->pgraph.intr_en &= 0x11111111; - else if(riva128->card_id < 0x10) riva128->pgraph.intr_en &= 0x00011311; - break; - case 0x400144: - if(riva128->card_id == 0x03) - { - riva128->pgraph.invalid_en = val; - riva128->pgraph.invalid_en &= 0x00011111; - } - break; - } - - if(riva128->card_id == 0x03) switch(addr) - { - case 0x400080: - riva128->pgraph.debug[0] = val & 0x13311110; - break; - case 0x400084: - riva128->pgraph.debug[1] = val & 0x10113301; - break; - case 0x400088: - riva128->pgraph.debug[2] = val & 0x1133f111; - break; - case 0x40008c: - riva128->pgraph.debug[3] = val & 0x1173ff31; - break; - case 0x400180: - riva128->pgraph.debug[1] &= ~1; //Clear recent volatile reset bit on object switch. - riva128->pgraph.ctx_switch[0] = val & 0x3ff3f71f; - break; - case 0x400190: - riva128->pgraph.ctx_control = val & 0x11010103; - break; - case 0x400194: - riva128->pgraph.ctx_user = val & 0x7f1fe000; - break; - case 0x4001a0: case 0x4001a4: case 0x4001a8: case 0x4001ac: case 0x4001b0: case 0x4001b4: case 0x4001b8: case 0x4001bc: - riva128->pgraph.ctx_cache[(addr & 0x1c) >> 2][0] = val & 0x3ff3f71f; - break; - case 0x40053c: - riva128->pgraph.uclip_xmin = val & 0x3ffff; - break; - case 0x400540: - riva128->pgraph.uclip_ymin = val & 0x3ffff; - break; - case 0x400544: - riva128->pgraph.uclip_xmax = val & 0x3ffff; - break; - case 0x400548: - riva128->pgraph.uclip_ymax = val & 0x3ffff; - break; - case 0x400550: - riva128->pgraph.src_canvas_min = val & (riva128->is_nv3t ? 0x7fff07ff : 0x3fff07ff); - break; - case 0x400554: - riva128->pgraph.src_canvas_max = val & (riva128->is_nv3t ? 0x7fff07ff : 0x3fff07ff); - break; - case 0x400558: - riva128->pgraph.dst_canvas_min = val & (riva128->is_nv3t ? 0x7fff07ff : 0x3fff07ff); - break; - case 0x40055c: - riva128->pgraph.dst_canvas_max = val & (riva128->is_nv3t ? 0x7fff07ff : 0x3fff07ff); - break; - case 0x400560: - riva128->pgraph.oclip_xmin = val & 0x3ffff; - break; - case 0x400564: - riva128->pgraph.oclip_ymin = val & 0x3ffff; - break; - case 0x400568: - riva128->pgraph.oclip_xmax = val & 0x3ffff; - break; - case 0x40056c: - riva128->pgraph.oclip_ymax = val & 0x3ffff; - break; - case 0x400624: - riva128->pgraph.rop = val & 0xff; - break; - case 0x40062c: - riva128->pgraph.chroma = val & 0x7fffffff; - break; - case 0x400630: - riva128->pgraph.surf_offset[0] = val & (riva128->is_nv3t ? 0x007fffff : 0x003fffff); - break; - case 0x400634: - riva128->pgraph.surf_offset[1] = val & (riva128->is_nv3t ? 0x007fffff : 0x003fffff); - break; - case 0x400638: - riva128->pgraph.surf_offset[2] = val & (riva128->is_nv3t ? 0x007fffff : 0x003fffff); - break; - case 0x40063c: - riva128->pgraph.surf_offset[3] = val & (riva128->is_nv3t ? 0x007fffff : 0x003fffff); - break; - case 0x400640: - { - uint32_t tmp = val & 0x7f800000; - if(val & 0x80000000) tmp = 0; - riva128->pgraph.beta = tmp; - break; - } - case 0x400650: - riva128->pgraph.surf_pitch[0] = val & 0x1ff0; - break; - case 0x400654: - riva128->pgraph.surf_pitch[1] = val & 0x1ff0; - break; - case 0x400658: - riva128->pgraph.surf_pitch[2] = val & 0x1ff0; - break; - case 0x40065c: - riva128->pgraph.surf_pitch[3] = val & 0x1ff0; - break; - case 0x400684: - riva128->pgraph.notify = val & 0x0011ffff; - break; - case 0x4006a0: - riva128->pgraph.cliprect_ctrl = val & 0x113; - break; - case 0x4006a4: - riva128->pgraph.fifo_enable = val & 1; - break; - case 0x401100: - riva128->pgraph.dma_intr &= ~val; - break; - case 0x401140: - riva128->pgraph.dma_intr_en = val & 0x00011111; - break; - } - else if(riva128->card_id < 0x10) switch(addr) - { - case 0x400080: - riva128->pgraph.debug[0] = val & 0x1337f000; - break; - case 0x400084: - riva128->pgraph.debug[1] = val & ((riva128->card_id == 0x04) ? 0x72113101 : 0xf2ffb701); - break; - case 0x400088: - riva128->pgraph.debug[2] = val & 0x11d7fff1; - break; - case 0x40008c: - riva128->pgraph.debug[3] = val & ((riva128->card_id == 0x04) ? 0x11ffff33 : 0xfbffff73); - break; - } - if(riva128->card_id >= 0x04) switch(addr) - { - case 0x400754: - riva128->pgraph.fifo_st2_addr = val; - break; - case 0x400758: - riva128->pgraph.fifo_st2_data = val; - rivatnt_pgraph_ctx_switch(riva128); - break; - } -} - - void riva128_pgraph_interrupt(int num, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - riva128->pgraph.intr |= (1 << num); - - riva128_pmc_interrupt(12, riva128); -} - - void riva128_pgraph_invalid_interrupt(int num, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - riva128->pgraph.invalid |= (1 << num); - - riva128_pgraph_interrupt(0, riva128); -} - -void riva128_pgraph_vblank_interrupt(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - riva128->pgraph.invalid |= (1 << 8); - - riva128_pmc_interrupt(24, riva128); -} - - uint8_t riva128_pramdac_read(uint32_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint8_t ret = 0; - - //nv_riva_log("RIVA 128 PRAMDAC read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - - switch(addr) - { - case 0x680500: - ret = riva128->pramdac.nvpll & 0xff; - break; - case 0x680501: - ret = (riva128->pramdac.nvpll >> 8) & 0xff; - break; - case 0x680502: - ret = (riva128->pramdac.nvpll >> 16) & 0xff; - break; - case 0x680503: - ret = (riva128->pramdac.nvpll >> 24) & 0xff; - break; - case 0x680504: - ret = riva128->pramdac.mpll & 0xff; - break; - case 0x680505: - ret = (riva128->pramdac.mpll >> 8) & 0xff; - break; - case 0x680506: - ret = (riva128->pramdac.mpll >> 16) & 0xff; - break; - case 0x680507: - ret = (riva128->pramdac.mpll >> 24) & 0xff; - break; - case 0x680508: - ret = riva128->pramdac.vpll & 0xff; - break; - case 0x680509: - ret = (riva128->pramdac.vpll >> 8) & 0xff; - break; - case 0x68050a: - ret = (riva128->pramdac.vpll >> 16) & 0xff; - break; - case 0x68050b: - ret = (riva128->pramdac.vpll >> 24) & 0xff; - break; - case 0x68050c: - ret = riva128->pramdac.pll_ctrl & 0xff; - break; - case 0x68050d: - ret = (riva128->pramdac.pll_ctrl >> 8) & 0xff; - break; - case 0x68050e: - ret = (riva128->pramdac.pll_ctrl >> 16) & 0xff; - break; - case 0x68050f: - ret = (riva128->pramdac.pll_ctrl >> 24) & 0xff; - break; - case 0x680600: - ret = riva128->pramdac.gen_ctrl & 0xff; - break; - case 0x680601: - ret = (riva128->pramdac.gen_ctrl >> 8) & 0xff; - break; - case 0x680602: - ret = (riva128->pramdac.gen_ctrl >> 16) & 0xff; - break; - case 0x680603: - ret = (riva128->pramdac.gen_ctrl >> 24) & 0xff; - break; - } - - return ret; -} - - void riva128_pramdac_write(uint32_t addr, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t* svga = &riva128->svga; - //nv_riva_log("RIVA 128 PRAMDAC write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - - switch(addr) - { - case 0x680500: - riva128->pramdac.nvpll = val; - riva128->pramdac.nv_m = val & 0xff; - riva128->pramdac.nv_n = (val >> 8) & 0xff; - riva128->pramdac.nv_p = (val >> 16) & 7; - svga_recalctimings(svga); - break; - case 0x680504: - riva128->pramdac.mpll = val; - riva128->pramdac.m_m = val & 0xff; - riva128->pramdac.m_n = (val >> 8) & 0xff; - riva128->pramdac.m_p = (val >> 16) & 7; - svga_recalctimings(svga); - break; - case 0x680508: - riva128->pramdac.vpll = val; - riva128->pramdac.v_m = val & 0xff; - riva128->pramdac.v_n = (val >> 8) & 0xff; - riva128->pramdac.v_p = (val >> 16) & 7; - svga_recalctimings(svga); - break; - case 0x68050c: - riva128->pramdac.pll_ctrl = val; - break; - case 0x680600: - riva128->pramdac.gen_ctrl = val; - break; - } -} - - uint32_t riva128_ramht_lookup(uint32_t handle, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint32_t ramht_base = riva128->pfifo.ramht_addr; - uint32_t ret = 0; - - uint32_t tmp = handle; - uint32_t hash = 0; - - int bits; - - switch(riva128->pfifo.ramht_size) - { - case 4096: - bits = 12; - case 8192: - bits = 13; - case 16384: - bits = 14; - case 32768: - bits = 15; - } - - while(tmp) - { - hash ^= (tmp & (riva128->pfifo.ramht_size - 1)); - tmp = tmp >> 1; - } - - hash ^= riva128->pfifo.caches[1].chanid << (bits - 4); - - ret = riva128->pramin[ramht_base + (hash * 8)]; - - nv_riva_log("RIVA 128 RAMHT lookup with handle %08X returned %08X %04X:%08X\n", handle, ret, CS, cpu_state.pc); - - return ret; -} - - void riva128_puller_exec_method(int chanid, int subchanid, int offset, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - nv_riva_log("RIVA 128 Puller executing method %04X on channel %01X[%01X] param %08X %04X:%08X\n", offset, chanid, subchanid, val, CS, cpu_state.pc); - - if(riva128->card_id == 0x03) - { - uint32_t tmp = riva128_ramht_lookup(val, riva128); - unsigned new_class = (tmp >> 16) & 0x1f; - unsigned old_subc = (riva128->pgraph.ctx_user >> 13) & 7; - unsigned new_subc = subchanid & 7; - riva128->pgraph.instance = (tmp & 0xffff) << 2; - if((old_subc != new_subc) || !offset) - { - uint32_t tmp_ctx = riva128->pramin[riva128->pgraph.instance]; - if(!offset) riva128->pgraph.ctx_cache[new_subc][0] = tmp_ctx & 0x3ff3f71f; - riva128->pgraph.ctx_user &= 0x1fe000; - riva128->pgraph.ctx_user |= tmp & 0x1f0000; - riva128->pgraph.ctx_user |= new_subc << 13; - if(riva128->pgraph.debug[1] & 0x100000) riva128->pgraph.ctx_switch[0] = riva128->pgraph.ctx_cache[new_subc][0]; - if(riva128->pgraph.debug[2] & 0x10000000) - { - //riva128_pgraph_volatile_reset(riva128); - riva128->pgraph.debug[1] |= 1; - } - else riva128->pgraph.debug[1] &= ~1; - if(riva128->pgraph.notify & 0x10000) - { - riva128_pgraph_invalid_interrupt(16, riva128); - riva128->pgraph.fifo_enable = 0; - } - } - - if(!riva128->pgraph.invalid && (((riva128->pgraph.debug[3] >> 20) & 3) == 3) && offset) - { - riva128_pgraph_invalid_interrupt(4, riva128); - riva128->pgraph.fifo_enable = 0; - } - - if((riva128->pgraph.debug[1] & 0x10000) && ((riva128->pgraph.instance >> 4) != riva128->pgraph.ctx_switch[3]) && (new_class == 0x0d || new_class == 0x0e || new_class == 0x14 || new_class == 0x17 || offset == 0x0104)) - { - riva128->pgraph.ctx_switch[3] = riva128->pgraph.instance >> 4; - riva128->pgraph.ctx_switch[1] = riva128->pramin[riva128->pgraph.instance + 4] & 0xffff; - riva128->pgraph.notify &= 0xf10000; - riva128->pgraph.notify |= (riva128->pramin[riva128->pgraph.instance + 4] >> 16) & 0xffff; - riva128->pgraph.ctx_switch[2] = riva128->pramin[riva128->pgraph.instance + 8] & 0x1ffff; - } - } - else rivatnt_pgraph_ctx_switch(riva128); -} - - void riva128_pusher_run(int chanid, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - - while(riva128->pfifo.channels[chanid].dmaget != riva128->pfifo.channels[chanid].dmaput) - { - uint32_t dmaget = riva128->pfifo.channels[chanid].dmaget; - uint32_t cmd = ((uint32_t*)svga->vram)[dmaget >> 2]; - uint32_t* params = (uint32_t *)(((uint32_t*)svga->vram)[(dmaget + 4) >> 2]); - if(((cmd & 0xe0000003) == 0x20000000) && (riva128->card_id >= 0x04)) - { - //old nv4 jump command - riva128->pfifo.channels[chanid].dmaget = cmd & 0x1ffffffc; - } - if((cmd & 0xe0030003) == 0) - { - //nv3 increasing method command - uint32_t method = cmd & 0x1ffc; - int subchannel = (cmd >> 13) & 7; - int method_count = (cmd >> 18) & 0x7ff; - int i; - for(i = 0; ipfifo.channels[chanid].dmaget += 4; - } -} - -uint8_t riva128_user_read(uint32_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - int chanid = (addr >> 16) & 0xf; - int subchanid = (addr >> 13) & 0x7; - int offset = addr & 0x1fff; - uint8_t ret = 0; - - nv_riva_log("RIVA 128 USER read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - - addr -= 0x800000; - - if(riva128->pfifo.chan_mode & (1 << chanid)) - { - //DMA mode reads??? - } - else - { - //PIO mode - switch(offset) - { - case 0x10: ret = riva128_pfifo_cache1_free(chanid, riva128) & 0xfc; break; - case 0x11: ret = riva128_pfifo_cache1_free(chanid, riva128) >> 8; break; - } - } - - return ret; -} - - void riva128_user_write(uint32_t addr, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - int chanid = (addr >> 16) & 0xf; - int subchanid = (addr >> 13) & 0x7; - int offset = addr & 0x1fff; - - nv_riva_log("RIVA 128 USER write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - - addr -= 0x800000; - - if(riva128->pfifo.chan_mode & (1 << chanid)) - { - //DMA mode, at least this has docs. - switch(offset) - { - case 0x40: - riva128->pfifo.channels[chanid].dmaput = val; - if(riva128->pfifo.caches[1].push_enabled) riva128_pusher_run(chanid, riva128); - break; - case 0x44: - riva128->pfifo.channels[chanid].dmaget = val; - break; - } - } - else - { - uint32_t err = -1; - int intr = 1; - //PIO mode - //if((offset & 0x1f00) && (offset != 0)) err = 5; //Reserved access - //if((offset & 0x1ff0) == 0x0020) intr = 0; - //if(!riva128->pfifo.caches[1].push_enabled) err = 1; //Pusher disabled - //else - { - riva128_puller_exec_method(chanid, subchanid, offset, val, riva128); - riva128->pgraph.status = 0x1f131111; //HACK - } - if(err != -1) - { - uint32_t w = (addr & 0x7fffff) | (err << 28); - if(intr) riva128_pfifo_interrupt(4, riva128); - - } - } -} - - uint8_t riva128_mmio_read(uint32_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint8_t ret = 0; - - addr &= 0xffffff; - - //This logging condition is necessary to prevent A CATASTROPHIC LOG BLOWUP when polling PTIMER or PFIFO. DO NOT REMOVE. - if(/*!((addr >= 0x009000) && (addr <= 0x009fff)) && !((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0x000000) - && (addr <= 0x000003)) && !((addr <= 0x680fff) && (addr >= 0x680000)) && !((addr >= 0x0c0000) && (addr <= 0x0cffff)) - && !((addr >= 0x110000) && (addr <= 0x11ffff)) && !(addr <= 0x000fff) && (addr >= 0x000000)*/1) nv_riva_log("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - - if((addr >= 0x000000) && (addr <= 0x000fff)) ret = riva128_pmc_read(addr, riva128); - if((addr >= 0x001000) && (addr <= 0x001fff)) ret = riva128_pbus_read(addr, riva128); - if((addr >= 0x002000) && (addr <= 0x002fff)) ret = riva128_pfifo_read(addr, riva128); - if((addr >= 0x009000) && (addr <= 0x009fff)) ret = riva128_ptimer_read(addr, riva128); - if((addr >= 0x100000) && (addr <= 0x100fff)) ret = riva128_pfb_read(addr, riva128); - if((addr >= 0x101000) && (addr <= 0x101fff)) ret = riva128_pextdev_read(addr, riva128); - if((addr >= 0x110000) && (addr <= 0x11ffff) && (riva128->card_id == 0x03)) ret = riva128->bios_rom.rom[addr & riva128->bios_rom.mask]; - if((addr >= 0x300000) && (addr <= 0x30ffff) && (riva128->card_id >= 0x04)) ret = riva128->bios_rom.rom[addr & riva128->bios_rom.mask]; - if((addr >= 0x400000) && (addr <= 0x400fff)) ret = riva128_pgraph_read(addr, riva128); - if((addr >= 0x680000) && (addr <= 0x680fff)) ret = riva128_pramdac_read(addr, riva128); - if(addr >= 0x800000) ret = riva128_user_read(addr, riva128); - - switch(addr) - { - case 0x6013b4: case 0x6013b5: - case 0x6013d4: case 0x6013d5: - case 0x6013da: - case 0x0c03c2: case 0x0c03c3: case 0x0c03c4: case 0x0c03c5: - case 0x6813c6: case 0x6813c7: case 0x6813c8: case 0x6813c9: case 0x6813ca: case 0x6813cb: case 0x6813cc: - ret = riva128_in(addr & 0xfff, riva128); - break; - } - return ret; -} - - uint16_t riva128_mmio_read_w(uint32_t addr, void *p) -{ - addr &= 0xffffff; - //nv_riva_log("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - return (riva128_mmio_read(addr+0,p) << 0) | (riva128_mmio_read(addr+1,p) << 8); -} - - uint32_t riva128_mmio_read_l(uint32_t addr, void *p) -{ - addr &= 0xffffff; - //nv_riva_log("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - return (riva128_mmio_read(addr+0,p) << 0) | (riva128_mmio_read(addr+1,p) << 8) | (riva128_mmio_read(addr+2,p) << 16) | (riva128_mmio_read(addr+3,p) << 24); -} - - void riva128_mmio_write(uint32_t addr, uint8_t val, void *p) -{ - addr &= 0xffffff; - //nv_riva_log("RIVA 128 MMIO write %08X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); - if(addr != 0x6013d4 && addr != 0x6013d5 && addr != 0x6013b4 && addr != 0x6013b5 && addr != 0x6013da && !((addr >= 0x6813c6) && (addr <= 0x6813cc))) - { - uint32_t tmp = riva128_mmio_read_l(addr,p); - tmp &= ~(0xff << ((addr & 3) << 3)); - tmp |= val << ((addr & 3) << 3); - riva128_mmio_write_l(addr, tmp, p); - } - else - { - riva128_out(addr & 0xfff, val & 0xff, p); - } -} - - void riva128_mmio_write_w(uint32_t addr, uint16_t val, void *p) -{ - uint32_t tmp; - addr &= 0xffffff; - //nv_riva_log("RIVA 128 MMIO write %08X %04X %04X:%08X\n", addr, val, CS, cpu_state.pc); - tmp = riva128_mmio_read_l(addr,p); - tmp &= ~(0xffff << ((addr & 2) << 4)); - tmp |= val << ((addr & 2) << 4); - riva128_mmio_write_l(addr, tmp, p); -} - - void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - addr &= 0xffffff; - - //DO NOT REMOVE. This fixes a monstrous log blowup in win9x's drivers when accessing PFIFO. - if(/*!((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0xc0000) && (addr <= 0xcffff)) && (addr != 0x000140)*/1) nv_riva_log("RIVA 128 MMIO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - - - if((addr >= 0x000000) && (addr <= 0x000fff)) riva128_pmc_write(addr, val, riva128); - if((addr >= 0x001000) && (addr <= 0x001fff)) riva128_pbus_write(addr, val, riva128); - if((addr >= 0x002000) && (addr <= 0x002fff)) riva128_pfifo_write(addr, val, riva128); - if((addr >= 0x009000) && (addr <= 0x009fff)) riva128_ptimer_write(addr, val, riva128); - if((addr >= 0x100000) && (addr <= 0x100fff)) riva128_pfb_write(addr, val, riva128); - if((addr >= 0x101000) && (addr <= 0x101fff)) riva128_pextdev_write(addr, val, riva128); - if((addr >= 0x400000) && (addr <= 0x400fff)) riva128_pgraph_write(addr, val, riva128); - if((addr >= 0x680000) && (addr <= 0x680fff)) riva128_pramdac_write(addr, val, riva128); - if((addr >= 0x800000) && (addr <= 0xffffff)) riva128_user_write(addr, val, riva128); - - switch(addr) - { - case 0x6013b4: case 0x6013b5: - case 0x6013d4: case 0x6013d5: - case 0x6013da: - case 0x0c03c2: case 0x0c03c3: case 0x0c03c4: case 0x0c03c5: - case 0x6813c6: case 0x6813c7: case 0x6813c8: case 0x6813c9: case 0x6813ca: case 0x6813cb: case 0x6813cc: - riva128_out(addr & 0xfff, val & 0xff, p); - riva128_out((addr+1) & 0xfff, (val>>8) & 0xff, p); - riva128_out((addr+2) & 0xfff, (val>>16) & 0xff, p); - riva128_out((addr+3) & 0xfff, (val>>24) & 0xff, p); - break; - } -} - -void riva128_ptimer_tick(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - //nv_riva_log("RIVA 128 PTIMER tick!\n"); - - double time = ((double)riva128->ptimer.clock_mul * 10000000.0f) / (double)riva128->ptimer.clock_div; - uint32_t tmp; - int alarm_check; - - //if(cs == 0x0008 && !riva128->pgraph.beta) nv_riva_log("RIVA 128 PTIMER time elapsed %f alarm %08x, time_low %08x\n", time, riva128->ptimer.alarm, riva128->ptimer.time & 0xffffffff); - - tmp = riva128->ptimer.time; - riva128->ptimer.time += (uint64_t)time; - - alarm_check = (riva128->ptimer.alarm - tmp) < (uint32_t)riva128->ptimer.time; - - if(alarm_check && (riva128->ptimer.intr_en & 1)) - { - //nv_riva_log("RIVA 128 PTIMER ALARM interrupt fired!\n"); - riva128_ptimer_interrupt(0, riva128); - } -} - - void riva128_mclk_poll(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - //if(!riva128->pgraph.beta) nv_riva_log("RIVA 128 MCLK poll PMC enable %08x\n", riva128->pmc.enable); - - if((riva128->pmc.enable & 0x00010000) && (riva128->card_id == 0x03)) riva128_ptimer_tick(riva128); - - riva128->mtime += (int64_t)((TIMER_USEC * 100000000.0) / riva128->mfreq); -} - - void riva128_nvclk_poll(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - if((riva128->pmc.enable & 0x00010000) && ((riva128->card_id < 0x40) && (riva128->card_id != 0x03))) riva128_ptimer_tick(riva128); - - riva128->nvtime += (int64_t)((TIMER_USEC * 100000000.0) / riva128->nvfreq); -} - - void riva128_vblank_start(svga_t *svga) -{ - riva128_t *riva128 = (riva128_t *)svga->p; - - riva128_pgraph_vblank_interrupt(riva128); -} - - uint8_t riva128_rma_in(uint16_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t* svga = &riva128->svga; - uint8_t ret = 0; - - addr &= 0xff; - - //nv_riva_log("RIVA 128 RMA read %04X %04X:%08X\n", addr, CS, cpu_state.pc); - - switch(addr) - { - case 0x00: - ret = 0x65; - break; - case 0x01: - ret = 0xd0; - break; - case 0x02: - ret = 0x16; - break; - case 0x03: - ret = 0x2b; - break; - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - if(riva128->rma.addr < 0x1000000) ret = riva128_mmio_read((riva128->rma.addr + (addr & 3)) & 0xffffff, riva128); - else ret = svga_read_linear((riva128->rma.addr - 0x1000000), svga); - break; - } - - return ret; -} - - void riva128_rma_out(uint16_t addr, uint8_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t* svga = &riva128->svga; - - addr &= 0xff; - - //nv_riva_log("RIVA 128 RMA write %04X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); - - switch(addr) - { - case 0x04: - riva128->rma.addr &= ~0xff; - riva128->rma.addr |= val; - break; - case 0x05: - riva128->rma.addr &= ~0xff00; - riva128->rma.addr |= (val << 8); - break; - case 0x06: - riva128->rma.addr &= ~0xff0000; - riva128->rma.addr |= (val << 16); - break; - case 0x07: - riva128->rma.addr &= ~0xff000000; - riva128->rma.addr |= (val << 24); - break; - case 0x08: - case 0x0c: - case 0x10: - case 0x14: - riva128->rma.data &= ~0xff; - riva128->rma.data |= val; - break; - case 0x09: - case 0x0d: - case 0x11: - case 0x15: - riva128->rma.data &= ~0xff00; - riva128->rma.data |= (val << 8); - break; - case 0x0a: - case 0x0e: - case 0x12: - case 0x16: - riva128->rma.data &= ~0xff0000; - riva128->rma.data |= (val << 16); - break; - case 0x0b: - case 0x0f: - case 0x13: - case 0x17: - riva128->rma.data &= ~0xff000000; - riva128->rma.data |= (val << 24); - if(riva128->rma.addr < 0x1000000) riva128_mmio_write_l(riva128->rma.addr & 0xffffff, riva128->rma.data, riva128); - else svga_writel_linear((riva128->rma.addr - 0x1000000), riva128->rma.data, svga); - break; - } - - if(addr & 0x10) riva128->rma.addr+=4; -} - - uint8_t riva128_in(uint16_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t* svga = &riva128->svga; - uint8_t ret = 0; - - if((addr >= 0x3d0) && (addr <= 0x3d3)) - { - //nv_riva_log("RIVA 128 RMA BAR Register read %04X %04X:%08X\n", addr, CS, cpu_state.pc); - if(!(riva128->rma.mode & 1)) return ret; - ret = riva128_rma_in(riva128->rma_addr + ((riva128->rma.mode & 0xe) << 1) + (addr & 3), riva128); - return ret; - } - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - // if (addr != 0x3da) nv_riva_log("S3 in %04X %04X:%08X ", addr, CS, cpu_state.pc); - switch (addr) - { - case 0x3D4: - ret = svga->crtcreg; - break; - case 0x3D5: - switch(svga->crtcreg) - { - case 0x28: - ret = svga->crtc[0x28] & 0x3f; - break; - case 0x34: - ret = svga->displine & 0xff; - break; - case 0x35: - ret = (svga->displine >> 8) & 7; - break; - case 0x3e: - //DDC status register - ret = (riva128->i2c.sda << 3) | (riva128->i2c.scl << 2); - if(riva128->i2c.state == I2C_READ) - { - if(riva128->i2c.scl) - { - if(riva128->i2c.databits > 8) - { - riva128->i2c.data <<= 1; - if(riva128->i2c.addr == 0xA1) - { - riva128->i2c.data |= (riva128->i2c.edid_rom.edid_rom[riva128->i2c.edid_rom.addr] & (0x80 >> riva128->i2c.databits)) >> riva128->i2c.databits; - } - else riva128->i2c.data = 0; - riva128->i2c.databits++; - } - if(riva128->i2c.databits == 8) - { - riva128->i2c.state = I2C_WAITACK; - riva128->i2c.sda = 0; - riva128->i2c.edid_rom.addr++; - } - } - } - break; - default: - ret = svga->crtc[svga->crtcreg]; - break; - } - if(svga->crtcreg > 0x18) - nv_riva_log("RIVA 128 Extended CRTC read %02X %04X:%08X\n", svga->crtcreg, CS, cpu_state.pc); - break; - default: - ret = svga_in(addr, svga); - break; - } - // if (addr != 0x3da) nv_riva_log("%02X\n", ret); - return ret; -} - - void riva128_out(uint16_t addr, uint8_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - - uint8_t old; - - if((addr >= 0x3d0) && (addr <= 0x3d3)) - { - //nv_riva_log("RIVA 128 RMA BAR Register write %04X %02x %04X:%08X\n", addr, val, CS, cpu_state.pc); - riva128->rma.access_reg[addr & 3] = val; - if(!(riva128->rma.mode & 1)) return; - riva128_rma_out(riva128->rma_addr + ((riva128->rma.mode & 0xe) << 1) + (addr & 3), riva128->rma.access_reg[addr & 3], riva128); - return; - } - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch(addr) - { - case 0x3D4: - svga->crtcreg = val; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - switch(svga->crtcreg) - { - case 0x1a: - svga_recalctimings(svga); - break; - case 0x1e: - riva128->read_bank = val; - if (svga->chain4) svga->read_bank = riva128->read_bank << 15; - else svga->read_bank = riva128->read_bank << 13; - break; - case 0x1d: - riva128->write_bank = val; - if (svga->chain4) svga->write_bank = riva128->write_bank << 15; - else svga->write_bank = riva128->write_bank << 13; - break; - case 0x26: - if (!svga->attrff) - svga->attraddr = val & 31; - break; - case 0x19: - case 0x25: - case 0x28: - case 0x2d: - svga_recalctimings(svga); - break; - case 0x38: - riva128->rma.mode = val & 0xf; - break; - case 0x3f: - //FULL EMULATION OF I2C AND DDC PROTOCOLS INCOMING - if(riva128->i2c.sda && riva128->i2c.scl && ((val & 0x30) == 0)) - { - riva128->i2c.state = I2C_START; - riva128->i2c.addr = 0; - riva128->i2c.addrbits = 0; - riva128->i2c.data = 0; - riva128->i2c.databits = 0; - } - else if(!riva128->i2c.sda && !riva128->i2c.scl && ((val & 0x30) == 0x30)) riva128->i2c.state = I2C_STOP; - else if(riva128->i2c.state == I2C_START) - { - if(val & 0x20) - { - if(riva128->i2c.addrbits > 8) - { - riva128->i2c.addr <<= 1; - riva128->i2c.addr |= (val >> 4) & 1; - riva128->i2c.addrbits++; - } - if(riva128->i2c.addrbits == 8) - { - riva128->i2c.state = I2C_WAITACK; - riva128->i2c.sda = 0; - if(riva128->i2c.addr == 0xA1) riva128->i2c.edid_rom.addr = 0; - } - } - } - else if(riva128->i2c.state == I2C_WAITACK) - { - if(riva128->i2c.edid_rom.addr == 0x80) - { - riva128->i2c.edid_rom.addr = 0; - riva128->i2c.state = I2C_STOP; - } - else riva128->i2c.state = I2C_READ; - } - - riva128->i2c.sda = (val >> 4) & 1; - riva128->i2c.scl = (val >> 5) & 1; - break; - } - //if(svga->crtcreg > 0x18) - // nv_riva_log("RIVA 128 Extended CRTC write %02X %02x %04X:%08X\n", svga->crtcreg, val, CS, cpu_state.pc); - if (old != val) - { - if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - return; - } - - svga_out(addr, val, svga); -} - - uint32_t riva128_ramin_readl(uint32_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint32_t ret = riva128->pramin[(addr & 0x1ffffc) >> 2]; - return ret; -} - - uint8_t riva128_ramin_readb(uint32_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint32_t ret = riva128->pramin[(addr & 0x1ffffc) >> 2]; - ret >>= 24 - ((addr & 3) << 3); - return ret; -} - - uint16_t riva128_ramin_readw(uint32_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint32_t ret = riva128->pramin[(addr & 0x1ffffc) >> 2]; - ret >>= 16 - ((addr & 2) << 3); - return ret; -} - - void riva128_ramin_writel(uint32_t addr, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - riva128->pramin[(addr & 0x1ffffc) >> 2] = val; -} - - void riva128_ramin_writeb(uint32_t addr, uint8_t val, void *p) -{ - uint32_t tmp = riva128_ramin_readl(addr,p); - tmp &= ~(0xff << ((addr & 3) << 3)); - tmp |= val << ((addr & 3) << 3); - riva128_ramin_writel(addr, tmp, p); -} - - void riva128_ramin_writew(uint32_t addr, uint16_t val, void *p) -{ - uint32_t tmp = riva128_ramin_readl(addr,p); - tmp &= ~(0xffff << ((addr & 2) << 4)); - tmp |= val << ((addr & 2) << 4); - riva128_ramin_writel(addr, tmp, p); -} - - uint8_t riva128_pci_read(int func, int addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint8_t ret = 0; - //nv_riva_log("RIVA 128 PCI read %02X %04X:%08X\n", addr, CS, cpu_state.pc); - switch (addr) - { - case 0x00: - ret = riva128->vendor_id & 0xff; - break; - case 0x01: - ret = riva128->vendor_id >> 8; - break; - - case 0x02: - ret = riva128->device_id & 0xff; - break; - case 0x03: - ret = riva128->device_id >> 8; - break; - - case 0x04: - ret = riva128->pci_regs[0x04] & 0x37; - break; - case 0x05: - ret = riva128->pci_regs[0x05] & 0x01; - break; - - case 0x06: - ret = 0x20; - break; - case 0x07: - ret = riva128->pci_regs[0x07] & 0x73; - break; - - case 0x08: - ret = 0x00; - break; /*Revision ID*/ - case 0x09: - ret = 0; - break; /*Programming interface*/ - - case 0x0a: - ret = 0x00; - break; /*Supports VGA interface*/ - case 0x0b: - ret = 0x03; /*output = 3; */break; - - case 0x0e: - ret = 0x00; - break; /*Header type*/ - - case 0x13: - case 0x17: - ret = riva128->pci_regs[addr]; - break; - - case 0x2c: - case 0x2d: - case 0x2e: - case 0x2f: - ret = riva128->pci_regs[addr]; - //if(CS == 0x0028) output = 3; - break; - - case 0x30: - return riva128->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ - case 0x31: - return 0x00; - case 0x32: - return riva128->pci_regs[0x32]; - case 0x33: - return riva128->pci_regs[0x33]; - - case 0x34: - ret = 0x00; - break; - - case 0x3c: - ret = riva128->pci_regs[0x3c]; - break; - - case 0x3d: - ret = 0x01; - break; /*INTA*/ - - case 0x3e: - ret = 0x03; - break; - case 0x3f: - ret = 0x01; - break; - - } - // nv_riva_log("%02X\n", ret); - return ret; -} - - void riva128_reenable_svga_mappings(svga_t *svga) -{ - switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } -} - - void riva128_pci_write(int func, int addr, uint8_t val, void *p) -{ - //nv_riva_log("RIVA 128 PCI write %02X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); - riva128_t *riva128 = (riva128_t *)p; - svga_t* svga = &riva128->svga; - switch (addr) - { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x3d: - case 0x3e: - case 0x3f: - return; - - case PCI_REG_COMMAND: - riva128->pci_regs[PCI_REG_COMMAND] = val & 0x27; - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&riva128->mmio_mapping); - mem_mapping_disable(&riva128->linear_mapping); - mem_mapping_disable(&riva128->ramin_mapping); - if (val & PCI_COMMAND_IO) - { - io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - } - else io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - if (val & PCI_COMMAND_MEM) - { - uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; - uint32_t linear_addr = riva128->pci_regs[0x17] << 24; - if (!mmio_addr && !linear_addr) - { - riva128_reenable_svga_mappings(svga); - } - if (mmio_addr) - { - mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); - } - if (linear_addr) - { - mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); - mem_mapping_set_addr(&riva128->ramin_mapping, linear_addr + 0xc00000, 0x200000); - } - } - return; - - case 0x05: - riva128->pci_regs[0x05] = val & 0x01; - return; - - case 0x07: - riva128->pci_regs[0x07] = (riva128->pci_regs[0x07] & 0x8f) | (val & 0x70); - return; - - case 0x13: - { - uint32_t mmio_addr; - riva128->pci_regs[addr] = val; - mmio_addr = riva128->pci_regs[0x13] << 24; - mem_mapping_disable(&riva128->mmio_mapping); - if (mmio_addr) - { - mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); - } - return; - } - - case 0x17: - { - uint32_t linear_addr; - riva128->pci_regs[addr] = val; - linear_addr = riva128->pci_regs[0x17] << 24; - mem_mapping_disable(&riva128->linear_mapping); - mem_mapping_disable(&riva128->ramin_mapping); - if (linear_addr) - { - mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0xc00000); - mem_mapping_set_addr(&riva128->ramin_mapping, linear_addr + 0xc00000, 0x200000); - } - return; - } - - case 0x30: - case 0x32: - case 0x33: - riva128->pci_regs[addr] = val; - mem_mapping_disable(&riva128->bios_rom.mapping); - if (riva128->pci_regs[0x30] & 0x01) - { - uint32_t addr = (riva128->pci_regs[0x32] << 16) | (riva128->pci_regs[0x33] << 24); - // nv_riva_log("RIVA 128 bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&riva128->bios_rom.mapping, addr, 0x8000); - } - return; - - case 0x3c: - riva128->pci_regs[0x3c] = val & 0x0f; - return; - - case 0x40: - case 0x41: - case 0x42: - case 0x43: - riva128->pci_regs[addr - 0x14] = val; //0x40-0x43 are ways to write to 0x2c-0x2f - return; - } -} - - void rivatnt_pci_write(int func, int addr, uint8_t val, void *p) -{ - //nv_riva_log("RIVA 128 PCI write %02X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - switch (addr) - { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x3d: - case 0x3e: - case 0x3f: - return; - - case PCI_REG_COMMAND: - riva128->pci_regs[PCI_REG_COMMAND] = val & 0x27; - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&riva128->mmio_mapping); - mem_mapping_disable(&riva128->linear_mapping); - if (val & PCI_COMMAND_IO) - { - io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - } - else io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - if (val & PCI_COMMAND_MEM) - { - uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; - uint32_t linear_addr = riva128->pci_regs[0x17] << 24; - if (!mmio_addr && !linear_addr) - { - riva128_reenable_svga_mappings(svga); - } - if (mmio_addr) - { - mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); - } - if (linear_addr) - { - mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); - } - } - return; - - case 0x05: - riva128->pci_regs[0x05] = val & 0x01; - return; - - case 0x07: - riva128->pci_regs[0x07] = (riva128->pci_regs[0x07] & 0x8f) | (val & 0x70); - return; - - case 0x13: - { - uint32_t mmio_addr; - riva128->pci_regs[addr] = val; - mmio_addr = riva128->pci_regs[0x13] << 24; - mem_mapping_disable(&riva128->mmio_mapping); - if (mmio_addr) - { - mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); - } - return; - } - - case 0x17: - { - uint32_t linear_addr; - riva128->pci_regs[addr] = val; - linear_addr = riva128->pci_regs[0x17] << 24; - mem_mapping_disable(&riva128->linear_mapping); - if (linear_addr) - { - mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); - } - return; - } - - case 0x30: - case 0x32: - case 0x33: - riva128->pci_regs[addr] = val; - mem_mapping_disable(&riva128->bios_rom.mapping); - if (riva128->pci_regs[0x30] & 0x01) - { - uint32_t addr = (riva128->pci_regs[0x32] << 16) | (riva128->pci_regs[0x33] << 24); - // nv_riva_log("RIVA TNT bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&riva128->bios_rom.mapping, addr, 0x10000); - } - return; - - case 0x3c: - riva128->pci_regs[0x3c] = val & 0x0f; - return; - - case 0x40: - case 0x41: - case 0x42: - case 0x43: - riva128->pci_regs[addr - 0x14] = val; //0x40-0x43 are ways to write to 0x2c-0x2f - return; - } -} - - void riva128_recalctimings(svga_t *svga) -{ - riva128_t *riva128 = (riva128_t *)svga->p; - - svga->ma_latch += (svga->crtc[0x19] & 0x1f) << 16; - svga->rowoffset += (svga->crtc[0x19] & 0xe0) << 3; - if (svga->crtc[0x25] & 0x01) svga->vtotal += 0x400; - if (svga->crtc[0x25] & 0x02) svga->dispend += 0x400; - if (svga->crtc[0x25] & 0x04) svga->vblankstart += 0x400; - if (svga->crtc[0x25] & 0x08) svga->vsyncstart += 0x400; - if (svga->crtc[0x25] & 0x10) svga->htotal += 0x100; - if (svga->crtc[0x2d] & 0x01) svga->hdisp += 0x100; - //The effects of the large screen bit seem to just be doubling the row offset. - //However, these large modes still don't work. Possibly core SVGA bug? It does report 640x2 res after all. - if (!(svga->crtc[0x1a] & 0x04)) svga->rowoffset <<= 1; - switch(svga->crtc[0x28] & 3) - { - case 1: - svga->bpp = 8; - svga->lowres = 0; - svga->render = svga_render_8bpp_highres; - break; - case 2: - svga->bpp = 16; - svga->lowres = 0; - svga->render = svga_render_16bpp_highres; - break; - case 3: - svga->bpp = 32; - svga->lowres = 0; - svga->render = svga_render_32bpp_highres; - break; - } - - /*if((svga->crtc[0x28] & 3) != 0) - { - if(svga->crtc[0x1a] & 2) svga_set_ramdac_type(svga, RAMDAC_6BIT); - else svga_set_ramdac_type(svga, RAMDAC_8BIT); - } - else svga_set_ramdac_type(svga, RAMDAC_6BIT);*/ - - double freq; - - if (((svga->miscout >> 2) & 2) == 2) - { - freq = 13500000.0; - - if(riva128->pramdac.v_m == 0) riva128->pramdac.v_m = 1; - else - { - freq = (freq * riva128->pramdac.v_n) / (1 << riva128->pramdac.v_p) / riva128->pramdac.v_m; - //nv_riva_log("RIVA 128 Pixel clock is %f Hz\n", freq); - } - - svga->clock = cpuclock / freq; - } - - if(riva128->card_id == 0x03) - { - freq = 13500000.0; - - if(riva128->pramdac.m_m == 0) riva128->pramdac.m_m = 1; - else - { - freq = (freq * riva128->pramdac.m_n) / (1 << riva128->pramdac.m_p) / riva128->pramdac.m_m; - //nv_riva_log("RIVA 128 Memory clock is %f Hz\n", freq); - } - - riva128->mfreq = freq; - riva128->mtime = (int64_t)((TIMER_USEC * 100000000.0) / riva128->mfreq); - riva128->menable = 1; - } - - if(riva128->card_id >= 0x04) - { - freq = 13500000.0; - - if(riva128->pramdac.nv_m == 0) riva128->pramdac.nv_m = 1; - else - { - freq = (freq * riva128->pramdac.nv_n) / (1 << riva128->pramdac.nv_p) / riva128->pramdac.nv_m; - //nv_riva_log("RIVA 128 Core clock is %f Hz\n", freq); - } - - riva128->nvfreq = freq; - riva128->nvtime = (int64_t)((TIMER_USEC * 100000000.0) / riva128->nvfreq); - riva128->nvenable = 1; - } -} - - -void *riva128_init(const device_t *info) -{ - riva128_t *riva128 = malloc(sizeof(riva128_t)); - memset(riva128, 0, sizeof(riva128_t)); - - riva128->card_id = 0x03; - riva128->is_nv3t = 0; - - riva128->vendor_id = 0x12d2; - riva128->device_id = 0x0018; - - riva128->memory_size = device_get_config_int("memory"); - - svga_init(&riva128->svga, riva128, riva128->memory_size << 20, - riva128_recalctimings, - riva128_in, riva128_out, - NULL, NULL); - - riva128->svga.decode_mask = (riva128->memory_size << 20) - 1; - - rom_init(&riva128->bios_rom, L"roms/video/nv_riva128/Diamond_V330_rev-e.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (PCI) - mem_mapping_disable(&riva128->bios_rom.mapping); - - mem_mapping_add(&riva128->mmio_mapping, 0, 0, - riva128_mmio_read, - riva128_mmio_read_w, - riva128_mmio_read_l, - riva128_mmio_write, - riva128_mmio_write_w, - riva128_mmio_write_l, - NULL, - 0, - riva128); - - mem_mapping_add(&riva128->ramin_mapping, 0, 0, - riva128_ramin_readb, - riva128_ramin_readw, - riva128_ramin_readl, - riva128_ramin_writeb, - riva128_ramin_writew, - riva128_ramin_writel, - NULL, - 0, - riva128); - - mem_mapping_add(&riva128->linear_mapping, 0, 0, - svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - 0, - &riva128->svga); - - io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - - // riva128->pci_regs[4] = 3; - riva128->pci_regs[4] = 7; - riva128->pci_regs[5] = 0; - riva128->pci_regs[6] = 0; - riva128->pci_regs[7] = 2; - - riva128->pci_regs[0x2c] = 0xd2; - riva128->pci_regs[0x2d] = 0x12; - riva128->pci_regs[0x2e] = 0x00; - riva128->pci_regs[0x2f] = 0x03; - - riva128->pci_regs[0x30] = 0x00; - riva128->pci_regs[0x32] = 0x0c; - riva128->pci_regs[0x33] = 0x00; - - riva128->pmc.intr = 0; - riva128->pbus.intr = 0; - riva128->pfifo.intr = 0; - riva128->pgraph.intr = 0; - riva128->ptimer.intr = 0; - riva128->ptimer.intr_en = 0xffffffff; - - riva128->pci_card = pci_add_card(PCI_ADD_VIDEO, riva128_pci_read, riva128_pci_write, riva128); - - riva128->ptimer.clock_mul = 1; - riva128->ptimer.clock_div = 1; - - //default values so that the emulator can boot. These'll be overwritten by the video BIOS anyway. - riva128->pramdac.m_m = 0x03; - riva128->pramdac.m_n = 0xc2; - riva128->pramdac.m_p = 0x0d; - - riva128->pramdac.nv_m = 0x03; - riva128->pramdac.nv_n = 0xc2; - riva128->pramdac.nv_p = 0x0d; - - riva128->i2c.addrbits = 0; - riva128->i2c.databits = 0; - riva128->i2c.state = I2C_STOP; - - uint8_t edid_rom[128] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x08, 0x01, 0x03, 0x81, 0x32, 0x26, 0x78, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x21, 0x08, 0x00, 0x61, 0x40, - 0x45, 0x40, 0x31, 0x40, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, - 0x00, 0xfd, 0x00, 0x01, 0xff, 0x01, 0xff, 0xff, - 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec}; - - { - int i = 0; - for(;i<128;i++) - { - riva128->i2c.edid_rom.edid_rom[i] = edid_rom[i]; - } - } - - riva128->menable = 1; - riva128->nvenable = 1; - - timer_add(riva128_mclk_poll, &riva128->mtime, &timer_one, riva128); - timer_add(riva128_nvclk_poll, &riva128->nvtime, &timer_one, riva128); - - riva128->svga.vblank_start = riva128_vblank_start; - - riva128->pgraph.beta = 0xffffffff; - - return riva128; -} - -void riva128_close(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - FILE *f = fopen("vram.dmp", "wb"); - fwrite(riva128->svga.vram, 4 << 20, 1, f); - fclose(f); - - svga_close(&riva128->svga); - - free(riva128); -} - -int riva128_available(void) -{ - return rom_present(L"roms/video/nv_riva128/Diamond_V330_rev-e.vbi"); -} - -void riva128_speed_changed(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - svga_recalctimings(&riva128->svga); -} - -void riva128_force_redraw(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - riva128->svga.fullchange = changeframecount; -} - -const device_config_t riva128_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, - { - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "" - } - }, - }, - { - "", "", -1 - } -}; - -#if 0 -const device_config_t riva128zx_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } -}; -#endif - -const device_t riva128_device = -{ - "nVidia RIVA 128", - DEVICE_PCI, - 0, - riva128_init, - riva128_close, - NULL, - riva128_available, - riva128_speed_changed, - riva128_force_redraw, - riva128_config -}; - - -void *rivatnt_init(const device_t *info) -{ - riva128_t *riva128 = malloc(sizeof(riva128_t)); - memset(riva128, 0, sizeof(riva128_t)); - - riva128->card_id = 0x04; - riva128->is_nv3t = 0; - - riva128->vendor_id = 0x10de; - riva128->device_id = 0x0020; - - riva128->memory_size = device_get_config_int("memory"); - - svga_init(&riva128->svga, riva128, riva128->memory_size << 20, - riva128_recalctimings, - riva128_in, riva128_out, - NULL, NULL); - - riva128->svga.decode_mask = (riva128->memory_size << 20) - 1; - - rom_init(&riva128->bios_rom, L"roms/video/nv_riva128/NV4_diamond_revB.rom", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - if (PCI) - mem_mapping_disable(&riva128->bios_rom.mapping); - - mem_mapping_add(&riva128->mmio_mapping, 0, 0, - riva128_mmio_read, - riva128_mmio_read_w, - riva128_mmio_read_l, - riva128_mmio_write, - riva128_mmio_write_w, - riva128_mmio_write_l, - NULL, - 0, - riva128); - mem_mapping_add(&riva128->linear_mapping, 0, 0, - svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - 0, - &riva128->svga); - - io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - - // riva128->pci_regs[4] = 3; - riva128->pci_regs[4] = 7; - riva128->pci_regs[5] = 0; - riva128->pci_regs[6] = 0; - riva128->pci_regs[7] = 2; - - riva128->pci_regs[0x2c] = 0x02; - riva128->pci_regs[0x2d] = 0x11; - riva128->pci_regs[0x2e] = 0x16; - riva128->pci_regs[0x2f] = 0x10; - - riva128->pci_regs[0x30] = 0x00; - riva128->pci_regs[0x32] = 0x0c; - riva128->pci_regs[0x33] = 0x00; - - riva128->pmc.intr = 0; - riva128->pbus.intr = 0; - riva128->pfifo.intr = 0; - riva128->pgraph.intr = 0; - - riva128->pci_card = pci_add_card(PCI_ADD_VIDEO, riva128_pci_read, rivatnt_pci_write, riva128); - - //default values so that the emulator can boot. These'll be overwritten by the video BIOS anyway. - riva128->pramdac.m_m = 0x03; - riva128->pramdac.m_n = 0xc2; - riva128->pramdac.m_p = 0x0d; - - riva128->pramdac.nv_m = 0x03; - riva128->pramdac.nv_n = 0xc2; - riva128->pramdac.nv_p = 0x0d; - - riva128->i2c.addrbits = 0; - riva128->i2c.databits = 0; - riva128->i2c.state = I2C_STOP; - - uint8_t edid_rom[128] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x08, 0x01, 0x03, 0x81, 0x32, 0x26, 0x78, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x21, 0x08, 0x00, 0x61, 0x40, - 0x45, 0x40, 0x31, 0x40, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, - 0x00, 0xfd, 0x00, 0x01, 0xff, 0x01, 0xff, 0xff, - 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec}; - - { - int i = 0; - for(;i<128;i++) - { - riva128->i2c.edid_rom.edid_rom[i] = edid_rom[i]; - } - } - - riva128->menable = 1; - riva128->nvenable = 1; - - timer_add(riva128_mclk_poll, &riva128->mtime, &timer_one, riva128); - timer_add(riva128_nvclk_poll, &riva128->nvtime, &timer_one, riva128); - - riva128->svga.vblank_start = riva128_vblank_start; - - return riva128; -} - -void rivatnt_close(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - FILE *f = fopen("vram.dmp", "wb"); - fwrite(riva128->svga.vram, 4 << 20, 1, f); - fclose(f); - - svga_close(&riva128->svga); - - free(riva128); -} - -int rivatnt_available(void) -{ - return rom_present(L"roms/video/nv_riva128/NV4_diamond_revB.rom"); -} - -void rivatnt_speed_changed(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - svga_recalctimings(&riva128->svga); -} - -void rivatnt_force_redraw(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - riva128->svga.fullchange = changeframecount; -} - -const device_config_t rivatnt_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 16, - { - { - "4 MB", 4 - }, - { - "8 MB", 8 - }, - { - "16 MB", 16 - }, - { - "" - } - }, - }, - { - "", "", -1 - } -}; - -const device_t rivatnt_device = -{ - "nVidia RIVA TNT", - DEVICE_PCI, - 0, - rivatnt_init, - rivatnt_close, - NULL, - rivatnt_available, - rivatnt_speed_changed, - rivatnt_force_redraw, - rivatnt_config -}; - -void *rivatnt2_init(const device_t *info) -{ - riva128_t *riva128 = malloc(sizeof(riva128_t)); - memset(riva128, 0, sizeof(riva128_t)); - - riva128->card_id = 0x05; - riva128->is_nv3t = 0; - - int model = device_get_config_int("model"); - - riva128->vendor_id = 0x10de; - riva128->device_id = ((model > 1) ? 0x0029 : 0x0028); - - riva128->memory_size = device_get_config_int("memory"); - - svga_init(&riva128->svga, riva128, riva128->memory_size << 20, - riva128_recalctimings, - riva128_in, riva128_out, - NULL, NULL); - - riva128->svga.decode_mask = 0x3fffff; - - switch(model) - { - case 0: - rom_init(&riva128->bios_rom, L"roms/video/nv_riva128/NV5diamond.bin", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - break; - case 1: - rom_init(&riva128->bios_rom, L"roms/video/nv_riva128/inno3d64bit.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - break; - case 2: - rom_init(&riva128->bios_rom, L"roms/video/nv_riva128/creative.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - break; - } - if (PCI) - mem_mapping_disable(&riva128->bios_rom.mapping); - - mem_mapping_add(&riva128->mmio_mapping, 0, 0, - riva128_mmio_read, - riva128_mmio_read_w, - riva128_mmio_read_l, - riva128_mmio_write, - riva128_mmio_write_w, - riva128_mmio_write_l, - NULL, - 0, - riva128); - mem_mapping_add(&riva128->linear_mapping, 0, 0, - svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - 0, - &riva128->svga); - - io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - - // riva128->pci_regs[4] = 3; - riva128->pci_regs[4] = 7; - riva128->pci_regs[5] = 0; - riva128->pci_regs[6] = 0; - riva128->pci_regs[7] = 2; - - riva128->pci_regs[0x2c] = 0x02; - riva128->pci_regs[0x2d] = 0x11; - riva128->pci_regs[0x2e] = 0x16; - riva128->pci_regs[0x2f] = 0x10; - - riva128->pci_regs[0x30] = 0x00; - riva128->pci_regs[0x32] = 0x0c; - riva128->pci_regs[0x33] = 0x00; - - riva128->pmc.intr = 0; - riva128->pbus.intr = 0; - riva128->pfifo.intr = 0; - riva128->pgraph.intr = 0; - - riva128->pci_card = pci_add_card(PCI_ADD_VIDEO, riva128_pci_read, rivatnt_pci_write, riva128); - - //default values so that the emulator can boot. These'll be overwritten by the video BIOS anyway. - riva128->pramdac.m_m = 0x03; - riva128->pramdac.m_n = 0xc2; - riva128->pramdac.m_p = 0x0d; - - riva128->pramdac.nv_m = 0x03; - riva128->pramdac.nv_n = 0xc2; - riva128->pramdac.nv_p = 0x0d; - - riva128->i2c.addrbits = 0; - riva128->i2c.databits = 0; - riva128->i2c.state = I2C_STOP; - - uint8_t edid_rom[128] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x08, 0x01, 0x03, 0x81, 0x32, 0x26, 0x78, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x21, 0x08, 0x00, 0x61, 0x40, - 0x45, 0x40, 0x31, 0x40, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, - 0x00, 0xfd, 0x00, 0x01, 0xff, 0x01, 0xff, 0xff, - 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec}; - - { - int i = 0; - for(;i<128;i++) - { - riva128->i2c.edid_rom.edid_rom[i] = edid_rom[i]; - } - } - - riva128->menable = 1; - riva128->nvenable = 1; - - timer_add(riva128_mclk_poll, &riva128->mtime, &timer_one, riva128); - timer_add(riva128_nvclk_poll, &riva128->nvtime, &timer_one, riva128); - - riva128->svga.vblank_start = riva128_vblank_start; - - return riva128; -} - -void rivatnt2_close(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - FILE *f = fopen("vram.dmp", "wb"); - fwrite(riva128->svga.vram, 4 << 20, 1, f); - fclose(f); - - svga_close(&riva128->svga); - - free(riva128); -} - -int rivatnt2_available(void) -{ - return rom_present(L"roms/video/nv_riva128/NV5diamond.bin") || rom_present(L"roms/video/nv_riva128/inno3d64bit.BIN") || rom_present(L"roms/video/nv_riva128/creative.BIN"); -} - -void rivatnt2_speed_changed(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - svga_recalctimings(&riva128->svga); -} - -void rivatnt2_force_redraw(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - riva128->svga.fullchange = changeframecount; -} - -const device_config_t rivatnt2_config[] = -{ - { - "model", "Card model", CONFIG_SELECTION, "", 0, - { - { - "Vanilla TNT2", 0, - }, - { - "TNT2 Pro", 1, - }, - { - "TNT2 Ultra", 2, - }, - }, - }, - { - "memory", "Memory size", CONFIG_SELECTION, "", 32, - { - { - "4 MB", 4 - }, - { - "8 MB", 8 - }, - { - "16 MB", 16 - }, - { - "32 MB", 32 - }, - { - "" - } - }, - }, - { - "", "", -1 - } -}; - -const device_t rivatnt2_device = -{ - "nVidia RIVA TNT2", - DEVICE_PCI, - 0, - rivatnt2_init, - rivatnt2_close, - NULL, - rivatnt2_available, - rivatnt2_speed_changed, - rivatnt2_force_redraw, - rivatnt2_config -}; diff --git a/backup code/video - Cópia/vid_nv_riva128.h b/backup code/video - Cópia/vid_nv_riva128.h deleted file mode 100644 index 8c8e2cd6b..000000000 --- a/backup code/video - Cópia/vid_nv_riva128.h +++ /dev/null @@ -1,3 +0,0 @@ -extern const device_t riva128_device; -extern const device_t rivatnt_device; -extern const device_t rivatnt2_device; diff --git a/backup code/video - Cópia/vid_nvidia.c b/backup code/video - Cópia/vid_nvidia.c deleted file mode 100644 index 2c210e0ac..000000000 --- a/backup code/video - Cópia/vid_nvidia.c +++ /dev/null @@ -1,965 +0,0 @@ -/* - * 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. - * - * nVidia RIVA 128 emulation. - * - * Version: @(#)vid_nv_riva128.c 1.0.7 2018/04/29 - * - * Author: Melissa Goad - * Miran Grca, - * - * Copyright 2015-2018 Melissa Goad. - * Copyright 2015-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../pic.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../plat.h" -#include "video.h" -#include "vid_nv_riva128.h" -#include "vid_svga.h" -#include "vid_svga_render.h" - -typedef struct riva128_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t mmio_mapping; - - rom_t bios_rom; - - svga_t svga; - - uint8_t card_id; - int pci_card; - int is_nv3t; - - uint16_t vendor_id; - uint16_t device_id; - - uint32_t linear_base, linear_size; - - uint16_t rma_addr; - - uint8_t pci_regs[256]; - - int memory_size; - - uint8_t ext_regs_locked; - - uint8_t read_bank; - uint8_t write_bank; - - struct - { - uint32_t intr; - uint32_t intr_en; - uint32_t intr_line; - uint32_t enable; - } pmc; - - struct - { - uint32_t intr; - uint32_t intr_en; - } pbus; - - struct - { - uint32_t cache_error; - uint32_t intr; - uint32_t intr_en; - - uint32_t ramht; - uint32_t ramht_addr; - uint32_t ramht_size; - - uint32_t ramfc; - uint32_t ramfc_addr; - - uint32_t ramro; - uint32_t ramro_addr; - uint32_t ramro_size; - - uint16_t chan_mode; - uint16_t chan_dma; - uint16_t chan_size; //0 = 1024, 1 = 512 - - uint32_t runout_put, runout_get; - - struct - { - uint32_t dmaput; - uint32_t dmaget; - } channels[16]; - - struct - { - int chanid; - int push_enabled; - int runout; - uint32_t get, put; - uint32_t ctx; - } caches[2]; - - struct - { - int subchan; - uint16_t method; - uint32_t param; - } cache0, cache1[64]; - } pfifo; - - struct - { - uint32_t addr; - uint32_t data; - uint8_t access_reg[4]; - uint8_t mode; - } rma; - - struct - { - uint32_t intr, intr_en; - - uint64_t time; - uint32_t alarm; - - uint16_t clock_mul, clock_div; - } ptimer; - - struct - { - int width; - int bpp; - uint32_t config_0; - } pfb; - - struct - { - uint32_t boot_0; - } pextdev; - - struct - { - int pgraph_speedhack; - - uint32_t obj_handle[8]; - uint16_t obj_class[8]; - - uint32_t debug[5]; - - uint32_t intr; - uint32_t intr_en; - - uint32_t invalid; - uint32_t invalid_en; - - uint32_t ctx_switch[5]; - uint32_t ctx_control; - uint32_t ctx_user; - uint32_t ctx_cache[8][5]; - - uint32_t fifo_enable; - - uint32_t fifo_st2_addr; - uint32_t fifo_st2_data; - - uint32_t uclip_xmin, uclip_ymin, uclip_xmax, uclip_ymax; - uint32_t oclip_xmin, oclip_ymin, oclip_xmax, oclip_ymax; - - uint32_t src_canvas_min, src_canvas_max; - uint32_t dst_canvas_min, dst_canvas_max; - - uint8_t rop; - - uint32_t chroma; - - uint32_t beta; - - uint32_t notify; - - //NV3 - uint32_t surf_offset[4]; - uint32_t surf_pitch[4]; - - uint32_t cliprect_min[2]; - uint32_t cliprect_max[2]; - uint32_t cliprect_ctrl; - - uint32_t instance; - - uint32_t dma_intr, dma_intr_en; - - uint32_t status; - } pgraph; - - struct - { - uint32_t nvpll; - uint32_t nv_m,nv_n,nv_p; - - uint32_t mpll; - uint32_t m_m,m_n,m_p; - - uint32_t vpll; - uint32_t v_m,v_n,v_p; - - uint32_t pll_ctrl; - - uint32_t gen_ctrl; - } pramdac; - - uint32_t channels[16][8][0x2000]; - - struct - { - int scl; - int sda; - } i2c; - - int64_t mtime, mfreq; -} riva128_t; - - -#ifdef ENABLE_NVIDIA_LOG -int nvidia_do_log = ENABLE_NVIDIA_LOG; -#endif - - -static void -nvidia_log(const char *fmt, ...) -{ -#ifdef ENABLE_NVIDIA_LOG - va_list ap; - - if (nvidia_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -uint8_t riva128_rma_in(uint16_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t* svga = &riva128->svga; - uint8_t ret = 0; - - addr &= 0xff; - - //nvidia_log("RIVA 128 RMA read %04X %04X:%08X\n", addr, CS, cpu_state.pc); - - switch(addr) - { - case 0x00: - ret = 0x65; - break; - case 0x01: - ret = 0xd0; - break; - case 0x02: - ret = 0x16; - break; - case 0x03: - ret = 0x2b; - break; - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - if(riva128->rma.addr < 0x1000000) /*ret = riva128_mmio_read((riva128->rma.addr + (addr & 3)) & 0xffffff, riva128);*/nvidia_log("RIVA 128 MMIO write %08x %08x\n", riva128->rma.addr & 0xffffff, riva128->rma.data); - else ret = svga_read_linear((riva128->rma.addr - 0x1000000), svga); - break; - } - - return ret; -} - -void riva128_rma_out(uint16_t addr, uint8_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t* svga = &riva128->svga; - - addr &= 0xff; - - //nvidia_log("RIVA 128 RMA write %04X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); - - switch(addr) - { - case 0x04: - riva128->rma.addr &= ~0xff; - riva128->rma.addr |= val; - break; - case 0x05: - riva128->rma.addr &= ~0xff00; - riva128->rma.addr |= (val << 8); - break; - case 0x06: - riva128->rma.addr &= ~0xff0000; - riva128->rma.addr |= (val << 16); - break; - case 0x07: - riva128->rma.addr &= ~0xff000000; - riva128->rma.addr |= (val << 24); - break; - case 0x08: - case 0x0c: - case 0x10: - case 0x14: - riva128->rma.data &= ~0xff; - riva128->rma.data |= val; - break; - case 0x09: - case 0x0d: - case 0x11: - case 0x15: - riva128->rma.data &= ~0xff00; - riva128->rma.data |= (val << 8); - break; - case 0x0a: - case 0x0e: - case 0x12: - case 0x16: - riva128->rma.data &= ~0xff0000; - riva128->rma.data |= (val << 16); - break; - case 0x0b: - case 0x0f: - case 0x13: - case 0x17: - riva128->rma.data &= ~0xff000000; - riva128->rma.data |= (val << 24); - if(riva128->rma.addr < 0x1000000) /*riva128_mmio_write_l(riva128->rma.addr & 0xffffff, riva128->rma.data, riva128);*/nvidia_log("RIVA 128 MMIO write %08x %08x\n", riva128->rma.addr & 0xffffff, riva128->rma.data); - else svga_writel_linear((riva128->rma.addr - 0x1000000), riva128->rma.data, svga); - break; - } - - if(addr & 0x10) riva128->rma.addr+=4; -} - -uint8_t riva128_in(uint16_t addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t* svga = &riva128->svga; - uint8_t ret = 0; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - // if (addr != 0x3da) nvidia_log("S3 in %04X %04X:%08X ", addr, CS, cpu_state.pc); - switch (addr) - { - case 0x3D4: - ret = svga->crtcreg; - break; - case 0x3D5: - switch(svga->crtcreg) - { - case 0x28: - ret = svga->crtc[0x28] & 0x3f; - break; - case 0x34: - ret = svga->displine & 0xff; - break; - case 0x35: - ret = (svga->displine >> 8) & 7; - break; - case 0x3e: - //DDC status register - ret = (riva128->i2c.sda << 3) | (riva128->i2c.scl << 2); - break; - default: - ret = svga->crtc[svga->crtcreg]; - break; - } - //if(svga->crtcreg > 0x18) - // nvidia_log("RIVA 128 Extended CRTC read %02X %04X:%08X\n", svga->crtcreg, CS, cpu_state.pc); - break; - default: - ret = svga_in(addr, svga); - break; - } - // if (addr != 0x3da) nvidia_log("%02X\n", ret); - return ret; -} - -void riva128_out(uint16_t addr, uint8_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - - uint8_t old; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch(addr) - { - case 0x3D4: - svga->crtcreg = val; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - switch(svga->crtcreg) - { - case 0x1e: - riva128->read_bank = val; - if (svga->chain4) svga->read_bank = riva128->read_bank << 15; - else svga->read_bank = riva128->read_bank << 13; - break; - case 0x1d: - riva128->write_bank = val; - if (svga->chain4) svga->write_bank = riva128->write_bank << 15; - else svga->write_bank = riva128->write_bank << 13; - break; - case 0x19: - case 0x1a: - case 0x25: - case 0x28: - case 0x2d: - svga_recalctimings(svga); - break; - case 0x38: - riva128->rma.mode = val & 0xf; - break; - case 0x3f: - riva128->i2c.sda = (val >> 4) & 1; - riva128->i2c.scl = (val >> 5) & 1; - break; - } - //if(svga->crtcreg > 0x18) - // nvidia_log("RIVA 128 Extended CRTC write %02X %02x %04X:%08X\n", svga->crtcreg, val, CS, cpu_state.pc); - if (old != val) - { - if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - return; - } - - svga_out(addr, val, svga); -} - -uint8_t riva128_pci_read(int func, int addr, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - uint8_t ret = 0; - //nvidia_log("RIVA 128 PCI read %02X %04X:%08X\n", addr, CS, cpu_state.pc); - switch (addr) - { - case 0x00: - ret = riva128->vendor_id & 0xff; - break; - case 0x01: - ret = riva128->vendor_id >> 8; - break; - - case 0x02: - ret = riva128->device_id & 0xff; - break; - case 0x03: - ret = riva128->device_id >> 8; - break; - - case 0x04: - ret = riva128->pci_regs[0x04] & 0x37; - break; - case 0x05: - ret = riva128->pci_regs[0x05] & 0x01; - break; - - case 0x06: - ret = 0x20; - break; - case 0x07: - ret = riva128->pci_regs[0x07] & 0x73; - break; - - case 0x08: - ret = 0x00; - break; /*Revision ID*/ - case 0x09: - ret = 0; - break; /*Programming interface*/ - - case 0x0a: - ret = 0x00; - break; /*Supports VGA interface*/ - case 0x0b: - ret = 0x03; /*output = 3; */break; - - case 0x0e: - ret = 0x00; - break; /*Header type*/ - - case 0x13: - case 0x17: - ret = riva128->pci_regs[addr]; - break; - - case 0x2c: - case 0x2d: - case 0x2e: - case 0x2f: - ret = riva128->pci_regs[addr]; - //if(CS == 0x0028) output = 3; - break; - - case 0x30: - return riva128->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ - case 0x31: - return 0x00; - case 0x32: - return riva128->pci_regs[0x32]; - case 0x33: - return riva128->pci_regs[0x33]; - - case 0x34: - ret = 0x00; - break; - - case 0x3c: - ret = riva128->pci_regs[0x3c]; - break; - - case 0x3d: - ret = 0x01; - break; /*INTA*/ - - case 0x3e: - ret = 0x03; - break; - case 0x3f: - ret = 0x01; - break; - - } - // nvidia_log("%02X\n", ret); - return ret; -} - -void riva128_reenable_svga_mappings(svga_t *svga) -{ - switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } -} - -void riva128_pci_write(int func, int addr, uint8_t val, void *p) -{ - //nvidia_log("RIVA 128 PCI write %02X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); - riva128_t *riva128 = (riva128_t *)p; - svga_t* svga = &riva128->svga; - switch (addr) - { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x3d: - case 0x3e: - case 0x3f: - return; - - case PCI_REG_COMMAND: - riva128->pci_regs[PCI_REG_COMMAND] = val & 0x27; - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&riva128->mmio_mapping); - mem_mapping_disable(&riva128->linear_mapping); - if (val & PCI_COMMAND_IO) - { - io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - } - else io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - if (val & PCI_COMMAND_MEM) - { - uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; - uint32_t linear_addr = riva128->pci_regs[0x17] << 24; - if (!mmio_addr && !linear_addr) - { - riva128_reenable_svga_mappings(svga); - } - if (mmio_addr) - { - mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); - } - if (linear_addr) - { - mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); - } - } - return; - - case 0x05: - riva128->pci_regs[0x05] = val & 0x01; - return; - - case 0x07: - riva128->pci_regs[0x07] = (riva128->pci_regs[0x07] & 0x8f) | (val & 0x70); - return; - - case 0x13: - { - uint32_t mmio_addr; - riva128->pci_regs[addr] = val; - mmio_addr = riva128->pci_regs[0x13] << 24; - mem_mapping_disable(&riva128->mmio_mapping); - if (mmio_addr) - { - mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); - } - return; - } - - case 0x17: - { - uint32_t linear_addr; - riva128->pci_regs[addr] = val; - linear_addr = riva128->pci_regs[0x17] << 24; - mem_mapping_disable(&riva128->linear_mapping); - if (linear_addr) - { - mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); - } - return; - } - - case 0x30: - case 0x32: - case 0x33: - riva128->pci_regs[addr] = val; - mem_mapping_disable(&riva128->bios_rom.mapping); - if (riva128->pci_regs[0x30] & 0x01) - { - uint32_t addr = (riva128->pci_regs[0x32] << 16) | (riva128->pci_regs[0x33] << 24); - // nvidia_log("RIVA 128 bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&riva128->bios_rom.mapping, addr, 0x8000); - } - return; - - case 0x3c: - riva128->pci_regs[0x3c] = val & 0x0f; - return; - - case 0x40: - case 0x41: - case 0x42: - case 0x43: - riva128->pci_regs[addr - 0x14] = val; //0x40-0x43 are ways to write to 0x2c-0x2f - return; - } -} - -void riva128_recalctimings(svga_t *svga) -{ - riva128_t *riva128 = (riva128_t *)svga->p; - - svga->ma_latch += (svga->crtc[0x19] & 0x1f) << 16; - svga->rowoffset += (svga->crtc[0x19] & 0xe0) << 3; - if (svga->crtc[0x25] & 0x01) svga->vtotal += 0x400; - if (svga->crtc[0x25] & 0x02) svga->dispend += 0x400; - if (svga->crtc[0x25] & 0x04) svga->vblankstart += 0x400; - if (svga->crtc[0x25] & 0x08) svga->vsyncstart += 0x400; - if (svga->crtc[0x25] & 0x10) svga->htotal += 0x100; - if (svga->crtc[0x2d] & 0x01) svga->hdisp += 0x100; - //The effects of the large screen bit seem to just be doubling the row offset. - //However, these large modes still don't work. Possibly core SVGA bug? It does report 640x2 res after all. - //if (!(svga->crtc[0x1a] & 0x04)) svga->rowoffset <<= 1; - switch(svga->crtc[0x28] & 3) - { - case 1: - svga->bpp = 8; - svga->lowres = 0; - svga->render = svga_render_8bpp_highres; - break; - case 2: - svga->bpp = 16; - svga->lowres = 0; - svga->render = svga_render_16bpp_highres; - break; - case 3: - svga->bpp = 32; - svga->lowres = 0; - svga->render = svga_render_32bpp_highres; - break; - } - - /*if((svga->crtc[0x28] & 3) != 0) - { - if(svga->crtc[0x1a] & 2) svga_set_ramdac_type(svga, RAMDAC_6BIT); - else svga_set_ramdac_type(svga, RAMDAC_8BIT); - } - else svga_set_ramdac_type(svga, RAMDAC_6BIT);*/ - - double freq; - - if (((svga->miscout >> 2) & 2) == 2) - { - freq = 13500000.0; - - if(riva128->pramdac.v_m == 0) riva128->pramdac.v_m = 1; - else - { - freq = (freq * riva128->pramdac.v_n) / (1 << riva128->pramdac.v_p) / riva128->pramdac.v_m; - //nvidia_log("RIVA 128 Pixel clock is %f Hz\n", freq); - } - - svga->clock = cpuclock / freq; - } - - if(riva128->card_id == 0x03) - { - freq = 13500000.0; - - if(riva128->pramdac.m_m == 0) riva128->pramdac.m_m = 1; - else - { - freq = (freq * riva128->pramdac.m_n) / (1 << riva128->pramdac.m_p) / riva128->pramdac.m_m; - //nvidia_log("RIVA 128 Memory clock is %f Hz\n", freq); - } - - riva128->mfreq = freq; - riva128->mtime = (int64_t)((TIMER_USEC * 100000000.0) / riva128->mfreq); - } -} - - -void *riva128_init(const device_t *info) -{ - riva128_t *riva128 = malloc(sizeof(riva128_t)); - memset(riva128, 0, sizeof(riva128_t)); - - riva128->card_id = 0x03; - riva128->is_nv3t = 0; - - riva128->vendor_id = 0x12d2; - riva128->device_id = 0x0018; - - riva128->memory_size = device_get_config_int("memory"); - - svga_init(&riva128->svga, riva128, riva128->memory_size << 20, - riva128_recalctimings, - riva128_in, riva128_out, - NULL, NULL); - - riva128->svga.decode_mask = (riva128->memory_size << 20) - 1; - - rom_init(&riva128->bios_rom, L"roms/video/nv_riva128/Diamond_V330_rev-e.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (PCI) - mem_mapping_disable(&riva128->bios_rom.mapping); - - /*mem_mapping_add(&riva128->mmio_mapping, 0, 0, - riva128_mmio_read, - riva128_mmio_read_w, - riva128_mmio_read_l, - riva128_mmio_write, - riva128_mmio_write_w, - riva128_mmio_write_l, - NULL, - 0, - riva128);*/ - - mem_mapping_add(&riva128->linear_mapping, 0, 0, - svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - 0, - &riva128->svga); - - io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - - // riva128->pci_regs[4] = 3; - riva128->pci_regs[4] = 7; - riva128->pci_regs[5] = 0; - riva128->pci_regs[6] = 0; - riva128->pci_regs[7] = 2; - - riva128->pci_regs[0x2c] = 0xd2; - riva128->pci_regs[0x2d] = 0x12; - riva128->pci_regs[0x2e] = 0x00; - riva128->pci_regs[0x2f] = 0x03; - - riva128->pci_regs[0x30] = 0x00; - riva128->pci_regs[0x32] = 0x0c; - riva128->pci_regs[0x33] = 0x00; - - riva128->pmc.intr = 0; - riva128->pbus.intr = 0; - riva128->pfifo.intr = 0; - riva128->pgraph.intr = 0; - riva128->ptimer.intr = 0; - - riva128->pci_card = pci_add_card(PCI_ADD_VIDEO, riva128_pci_read, riva128_pci_write, riva128); - - riva128->ptimer.clock_mul = 1; - riva128->ptimer.clock_div = 1; - - //default values so that the emulator can boot. These'll be overwritten by the video BIOS anyway. - riva128->pramdac.m_m = 0x03; - riva128->pramdac.m_n = 0xc2; - riva128->pramdac.m_p = 0x0d; - - //timer_add(riva128_mclk_poll, &riva128->mtime, &timer_one, riva128); - - return riva128; -} - -void riva128_close(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - FILE *f = fopen("vram.dmp", "wb"); - fwrite(riva128->svga.vram, 4 << 20, 1, f); - fclose(f); - - svga_close(&riva128->svga); - - free(riva128); -} - -int riva128_available(void) -{ - return rom_present(L"roms/video/nv_riva128/Diamond_V330_rev-e.vbi"); -} - -void riva128_speed_changed(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - svga_recalctimings(&riva128->svga); -} - -void riva128_force_redraw(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - - riva128->svga.fullchange = changeframecount; -} - -const device_config_t riva128_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, - { - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "" - } - }, - }, - { - "", "", -1 - } -}; - -#if 0 -const device_config_t riva128zx_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } -}; -#endif - -const device_t riva128_device = -{ - "nVidia RIVA 128", - DEVICE_PCI, - 0, - riva128_init, - riva128_close, - NULL, - riva128_available, - riva128_speed_changed, - riva128_force_redraw, - riva128_config -}; \ No newline at end of file diff --git a/backup code/video - Cópia/vid_nvidia.h b/backup code/video - Cópia/vid_nvidia.h deleted file mode 100644 index c55533d2c..000000000 --- a/backup code/video - Cópia/vid_nvidia.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t riva128_device; diff --git a/backup code/video - Cópia/vid_oak_oti.c b/backup code/video - Cópia/vid_oak_oti.c deleted file mode 100644 index 9d166d6e0..000000000 --- a/backup code/video - Cópia/vid_oak_oti.c +++ /dev/null @@ -1,423 +0,0 @@ -/* - * 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. - * - * Oak OTI037C/67/077 emulation. - * - * Version: @(#)vid_oak_oti.c 1.0.12 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "video.h" -#include "vid_oak_oti.h" -#include "vid_svga.h" - -#define BIOS_37C_PATH L"roms/video/oti/bios.bin" -#define BIOS_77_PATH L"roms/video/oti/oti077.vbi" - - -typedef struct { - svga_t svga; - - rom_t bios_rom; - - int index; - uint8_t regs[32]; - - uint8_t pos; - - uint8_t enable_register; - - uint32_t vram_size; - uint32_t vram_mask; - - uint8_t chip_id; -} oti_t; - - -static void -oti_out(uint16_t addr, uint8_t val, void *p) -{ - oti_t *oti = (oti_t *)p; - svga_t *svga = &oti->svga; - uint8_t old; - uint8_t idx; - - if (!(oti->enable_register & 1) && addr != 0x3C3) - return; - - if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && - !(svga->miscout & 1)) addr ^= 0x60; - - switch (addr) { - case 0x3C3: - oti->enable_register = val & 1; - return; - - case 0x3D4: - svga->crtcreg = val; - return; - - case 0x3D5: - if (svga->crtcreg & 0x20) - return; - if (((svga->crtcreg & 31) < 7) && (svga->crtc[0x11] & 0x80)) - return; - if (((svga->crtcreg & 31) == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg & 31]; - svga->crtc[svga->crtcreg & 31] = val; - if (old != val) { - if ((svga->crtcreg & 31) < 0xE || (svga->crtcreg & 31) > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - - case 0x3DE: - oti->index = val; - return; - - case 0x3DF: - idx = oti->index & 0x1f; - oti->regs[idx] = val; - switch (idx) { - case 0xD: - if (oti->chip_id) - { - svga->vram_display_mask = (val & 0xc) ? oti->vram_mask : 0x3ffff; - if ((val & 0x80) && oti->vram_size == 256) - mem_mapping_disable(&svga->mapping); - else - mem_mapping_enable(&svga->mapping); - if (!(val & 0x80)) - svga->vram_display_mask = 0x3ffff; - } - else - { - if (val & 0x80) - mem_mapping_disable(&svga->mapping); - else - mem_mapping_enable(&svga->mapping); - } - break; - - case 0x11: - svga->read_bank = (val & 0xf) * 65536; - svga->write_bank = (val >> 4) * 65536; - break; - } - return; - } - - svga_out(addr, val, svga); -} - - -static uint8_t -oti_in(uint16_t addr, void *p) -{ - oti_t *oti = (oti_t *)p; - svga_t *svga = &oti->svga; - uint8_t temp; - - if (!(oti->enable_register & 1) && addr != 0x3C3) - return 0xff; - - if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && - !(svga->miscout & 1)) addr ^= 0x60; - - switch (addr) { - case 0x3C3: - temp = oti->enable_register; - break; - - case 0x3D4: - temp = svga->crtcreg; - break; - - case 0x3D5: - if (svga->crtcreg & 0x20) - temp = 0xff; - else - temp = svga->crtc[svga->crtcreg & 31]; - break; - - case 0x3DA: - svga->attrff = 0; - svga->attrff = 0; - svga->cgastat &= ~0x30; - /* copy color diagnostic info from the overscan color register */ - switch (svga->attrregs[0x12] & 0x30) - { - case 0x00: /* P0 and P2 */ - if (svga->attrregs[0x11] & 0x01) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x04) - svga->cgastat |= 0x20; - break; - case 0x10: /* P4 and P5 */ - if (svga->attrregs[0x11] & 0x10) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x20) - svga->cgastat |= 0x20; - break; - case 0x20: /* P1 and P3 */ - if (svga->attrregs[0x11] & 0x02) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x08) - svga->cgastat |= 0x20; - break; - case 0x30: /* P6 and P7 */ - if (svga->attrregs[0x11] & 0x40) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x80) - svga->cgastat |= 0x20; - break; - } - return svga->cgastat; - - case 0x3DE: - temp = oti->index | (oti->chip_id << 5); - break; - - case 0x3DF: - if ((oti->index & 0x1f)==0x10) - temp = 0x18; - else - temp = oti->regs[oti->index & 0x1f]; - break; - - default: - temp = svga_in(addr, svga); - break; - } - - return(temp); -} - - -static void -oti_pos_out(uint16_t addr, uint8_t val, void *p) -{ - oti_t *oti = (oti_t *)p; - - if ((val & 8) != (oti->pos & 8)) { - if (val & 8) - io_sethandler(0x03c0, 32, oti_in, NULL, NULL, - oti_out, NULL, NULL, oti); - else - io_removehandler(0x03c0, 32, oti_in, NULL, NULL, - oti_out, NULL, NULL, oti); - } - - oti->pos = val; -} - - -static uint8_t -oti_pos_in(uint16_t addr, void *p) -{ - oti_t *oti = (oti_t *)p; - - return(oti->pos); -} - - -static void -oti_recalctimings(svga_t *svga) -{ - oti_t *oti = (oti_t *)svga->p; - - if (oti->regs[0x14] & 0x08) svga->ma_latch |= 0x10000; - - if (oti->regs[0x0d] & 0x0c) svga->rowoffset <<= 1; - - svga->interlace = oti->regs[0x14] & 0x80; -} - - -static void * -oti_init(const device_t *info) -{ - oti_t *oti = malloc(sizeof(oti_t)); - wchar_t *romfn = NULL; - - memset(oti, 0x00, sizeof(oti_t)); - oti->chip_id = info->local; - - switch(oti->chip_id) { - case 0: - romfn = BIOS_37C_PATH; - break; - - case 2: - case 5: - romfn = BIOS_77_PATH; - break; - } - - rom_init(&oti->bios_rom, romfn, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - oti->vram_size = device_get_config_int("memory"); - oti->vram_mask = (oti->vram_size << 10) - 1; - - svga_init(&oti->svga, oti, oti->vram_size << 10, - oti_recalctimings, oti_in, oti_out, NULL, NULL); - - io_sethandler(0x03c0, 32, - oti_in, NULL, NULL, oti_out, NULL, NULL, oti); - io_sethandler(0x46e8, 1, oti_pos_in,NULL,NULL, oti_pos_out,NULL,NULL, oti); - - oti->svga.miscout = 1; - - oti->regs[0] = 0x08; /* fixme: bios wants to read this at index 0? this index is undocumented */ - - return(oti); -} - - -static void -oti_close(void *p) -{ - oti_t *oti = (oti_t *)p; - - svga_close(&oti->svga); - - free(oti); -} - - -static void -oti_speed_changed(void *p) -{ - oti_t *oti = (oti_t *)p; - - svga_recalctimings(&oti->svga); -} - - -static void -oti_force_redraw(void *p) -{ - oti_t *oti = (oti_t *)p; - - oti->svga.fullchange = changeframecount; -} - - -static int -oti037c_available(void) -{ - return(rom_present(BIOS_37C_PATH)); -} - - -static int -oti067_077_available(void) -{ - return(rom_present(BIOS_77_PATH)); -} - - -static const device_config_t oti067_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 512, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -static const device_config_t oti077_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 1024, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "1 MB", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -const device_t oti037c_device = -{ - "Oak OTI-037C", - DEVICE_ISA, - 0, - oti_init, oti_close, NULL, - oti037c_available, - oti_speed_changed, - oti_force_redraw, - oti067_config -}; - -const device_t oti067_device = -{ - "Oak OTI-067", - DEVICE_ISA, - 2, - oti_init, oti_close, NULL, - oti067_077_available, - oti_speed_changed, - oti_force_redraw, - oti067_config -}; - -const device_t oti077_device = -{ - "Oak OTI-077", - DEVICE_ISA, - 5, - oti_init, oti_close, NULL, - oti067_077_available, - oti_speed_changed, - oti_force_redraw, - oti077_config -}; diff --git a/backup code/video - Cópia/vid_oak_oti.h b/backup code/video - Cópia/vid_oak_oti.h deleted file mode 100644 index 6a4d3cb1f..000000000 --- a/backup code/video - Cópia/vid_oak_oti.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -extern const device_t oti037c_device; -extern const device_t oti067_device; -extern const device_t oti067_acer386_device; -extern const device_t oti077_device; diff --git a/backup code/video - Cópia/vid_paradise.c b/backup code/video - Cópia/vid_paradise.c deleted file mode 100644 index 2342c353a..000000000 --- a/backup code/video - Cópia/vid_paradise.c +++ /dev/null @@ -1,617 +0,0 @@ -/* - * 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. - * - * Paradise VGA emulation - * PC2086, PC3086 use PVGA1A - * MegaPC uses W90C11A - * - * Version: @(#)vid_paradise.c 1.0.7 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "video.h" -#include "vid_paradise.h" -#include "vid_svga.h" -#include "vid_svga_render.h" - - -typedef struct paradise_t -{ - svga_t svga; - - rom_t bios_rom; - - enum - { - PVGA1A = 0, - WD90C11, - WD90C30 - } type; - - uint32_t read_bank[4], write_bank[4]; -} paradise_t; - -void paradise_remap(paradise_t *paradise); - - -void paradise_out(uint16_t addr, uint8_t val, void *p) -{ - paradise_t *paradise = (paradise_t *)p; - svga_t *svga = ¶dise->svga; - uint8_t old; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - switch (addr) - { - case 0x3c5: - if (svga->seqaddr > 7) - { - if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) - return; - svga->seqregs[svga->seqaddr & 0x1f] = val; - if (svga->seqaddr == 0x11) - paradise_remap(paradise); - return; - } - break; - - case 0x3cf: - if (svga->gdcaddr >= 0x9 && svga->gdcaddr < 0xf) - { - if ((svga->gdcreg[0xf] & 7) != 5) - return; - } - if (svga->gdcaddr == 6) - { - if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) - { - switch (val&0xC) - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - } - svga->gdcreg[6] = val; - paradise_remap(paradise); - return; - } - if (svga->gdcaddr == 0x9 || svga->gdcaddr == 0xa) - { - svga->gdcreg[svga->gdcaddr] = val; - paradise_remap(paradise); - return; - } - if (svga->gdcaddr == 0xe) - { - svga->gdcreg[0xe] = val; - paradise_remap(paradise); - return; - } - break; - - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) - return; - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg > 0x29 && (svga->crtc[0x29] & 7) != 5) - return; - if (svga->crtcreg >= 0x31 && svga->crtcreg <= 0x37) - return; - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(¶dise->svga); - } - } - break; - } - svga_out(addr, val, svga); -} - -uint8_t paradise_in(uint16_t addr, void *p) -{ - paradise_t *paradise = (paradise_t *)p; - svga_t *svga = ¶dise->svga; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3c2: - return 0x10; - - case 0x3c5: - if (svga->seqaddr > 7) - { - if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) - return 0xff; - if (svga->seqaddr > 0x12) - return 0xff; - return svga->seqregs[svga->seqaddr & 0x1f]; - } - break; - - case 0x3cf: - if (svga->gdcaddr >= 0x9 && svga->gdcaddr < 0xf) - { - if (svga->gdcreg[0xf] & 0x10) - return 0xff; - switch (svga->gdcaddr) - { - case 0xf: - return (svga->gdcreg[0xf] & 0x17) | 0x80; - } - } - break; - - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) - return 0xff; - if (svga->crtcreg > 0x29 && svga->crtcreg < 0x30 && (svga->crtc[0x29] & 0x88) != 0x80) - return 0xff; - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); -} - -void paradise_remap(paradise_t *paradise) -{ - svga_t *svga = ¶dise->svga; - - uint8_t mask = (paradise->type == WD90C11) ? 0x7f : 0xff; - - if (svga->seqregs[0x11] & 0x80) - { - paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & mask) << 12; - paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & mask) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & mask) << 12; - paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0xa] & mask) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } - else if (svga->gdcreg[0xe] & 0x08) - { - if (svga->gdcreg[0x6] & 0xc) - { - paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0xa] & mask) << 12; - paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & mask) << 12; - paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & mask) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & mask) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } - else - { - paradise->read_bank[0] = paradise->write_bank[0] = (svga->gdcreg[0xa] & mask) << 12; - paradise->read_bank[1] = paradise->write_bank[1] = ((svga->gdcreg[0xa] & mask) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->read_bank[2] = paradise->write_bank[2] = (svga->gdcreg[0x9] & mask) << 12; - paradise->read_bank[3] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & mask) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } - } - else - { - paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & mask) << 12; - paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & mask) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0x9] & mask) << 12; - paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & mask) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } -} - -void paradise_recalctimings(svga_t *svga) -{ - paradise_t *paradise = (paradise_t *) svga->p; - - if (paradise->type == WD90C30) - svga->interlace = (svga->crtc[0x2d] & 0x20); - - svga->lowres = !(svga->gdcreg[0xe] & 0x01); - if (svga->bpp == 8 && !svga->lowres) - svga->render = svga_render_8bpp_highres; -} - -static void paradise_write(uint32_t addr, uint8_t val, void *p) -{ - paradise_t *paradise = (paradise_t *)p; - addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; - - svga_write_linear(addr, val, ¶dise->svga); -} -static void paradise_writew(uint32_t addr, uint16_t val, void *p) -{ - paradise_t *paradise = (paradise_t *)p; - addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; - svga_writew_linear(addr, val, ¶dise->svga); -} - -static uint8_t paradise_read(uint32_t addr, void *p) -{ - paradise_t *paradise = (paradise_t *)p; - addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; - return svga_read_linear(addr, ¶dise->svga); -} -static uint16_t paradise_readw(uint32_t addr, void *p) -{ - paradise_t *paradise = (paradise_t *)p; - addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; - return svga_readw_linear(addr, ¶dise->svga); -} - -void *paradise_pvga1a_init(const device_t *info, uint32_t memsize) -{ - paradise_t *paradise = malloc(sizeof(paradise_t)); - svga_t *svga = ¶dise->svga; - memset(paradise, 0, sizeof(paradise_t)); - - io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - - svga_init(¶dise->svga, paradise, memsize, /*256kb*/ - NULL, - paradise_in, paradise_out, - NULL, - NULL); - - mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL); - mem_mapping_set_p(¶dise->svga.mapping, paradise); - - svga->crtc[0x31] = 'W'; - svga->crtc[0x32] = 'D'; - svga->crtc[0x33] = '9'; - svga->crtc[0x34] = '0'; - svga->crtc[0x35] = 'C'; - - svga->bpp = 8; - svga->miscout = 1; - - paradise->type = PVGA1A; - - return paradise; -} - -void *paradise_wd90c11_init(const device_t *info) -{ - paradise_t *paradise = malloc(sizeof(paradise_t)); - svga_t *svga = ¶dise->svga; - memset(paradise, 0, sizeof(paradise_t)); - - io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - - svga_init(¶dise->svga, paradise, 1 << 19, /*512kb*/ - paradise_recalctimings, - paradise_in, paradise_out, - NULL, - NULL); - - mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL); - mem_mapping_set_p(¶dise->svga.mapping, paradise); - - svga->crtc[0x31] = 'W'; - svga->crtc[0x32] = 'D'; - svga->crtc[0x33] = '9'; - svga->crtc[0x34] = '0'; - svga->crtc[0x35] = 'C'; - svga->crtc[0x36] = '1'; - svga->crtc[0x37] = '1'; - - svga->bpp = 8; - svga->miscout = 1; - - paradise->type = WD90C11; - - return paradise; -} - -void *paradise_wd90c30_init(const device_t *info, uint32_t memsize) -{ - paradise_t *paradise = malloc(sizeof(paradise_t)); - svga_t *svga = ¶dise->svga; - memset(paradise, 0, sizeof(paradise_t)); - - io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - - svga_init(¶dise->svga, paradise, memsize, - paradise_recalctimings, - paradise_in, paradise_out, - NULL, - NULL); - - mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL); - mem_mapping_set_p(¶dise->svga.mapping, paradise); - - svga->crtc[0x31] = 'W'; - svga->crtc[0x32] = 'D'; - svga->crtc[0x33] = '9'; - svga->crtc[0x34] = '0'; - svga->crtc[0x35] = 'C'; - svga->crtc[0x36] = '3'; - svga->crtc[0x37] = '0'; - - svga->bpp = 8; - svga->miscout = 1; - - paradise->type = WD90C11; - - return paradise; -} - -static void *paradise_pvga1a_pc2086_init(const device_t *info) -{ - paradise_t *paradise = paradise_pvga1a_init(info, 1 << 18); - - if (paradise) - rom_init(¶dise->bios_rom, L"roms/machines/pc2086/40186.ic171", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - return paradise; -} -static void *paradise_pvga1a_pc3086_init(const device_t *info) -{ - paradise_t *paradise = paradise_pvga1a_init(info, 1 << 18); - - if (paradise) - rom_init(¶dise->bios_rom, L"roms/machines/pc3086/c000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - return paradise; -} - -static void *paradise_pvga1a_standalone_init(const device_t *info) -{ - paradise_t *paradise; - uint32_t memory = 512; - - memory = device_get_config_int("memory"); - memory <<= 10; - - paradise = paradise_pvga1a_init(info, memory); - - if (paradise) - rom_init(¶dise->bios_rom, L"roms/video/pvga1a/BIOS.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - return paradise; -} - -static int paradise_pvga1a_standalone_available(void) -{ - return rom_present(L"roms/video/pvga1a/BIOS.BIN"); -} - -static void *paradise_wd90c11_megapc_init(const device_t *info) -{ - paradise_t *paradise = paradise_wd90c11_init(info); - - if (paradise) - rom_init_interleaved(¶dise->bios_rom, - L"roms/machines/megapc/41651-bios lo.u18", - L"roms/machines/megapc/211253-bios hi.u19", - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - return paradise; -} - -static void *paradise_wd90c11_standalone_init(const device_t *info) -{ - paradise_t *paradise = paradise_wd90c11_init(info); - - if (paradise) - rom_init(¶dise->bios_rom, L"roms/video/wd90c11/WD90C11.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - return paradise; -} - -static int paradise_wd90c11_standalone_available(void) -{ - return rom_present(L"roms/video/wd90c11/WD90C11.VBI"); -} - -static void *paradise_wd90c30_standalone_init(const device_t *info) -{ - paradise_t *paradise; - uint32_t memory = 512; - - memory = device_get_config_int("memory"); - memory <<= 10; - - paradise = paradise_wd90c30_init(info, memory); - - if (paradise) - rom_init(¶dise->bios_rom, L"roms/video/wd90c30/90C30-LR.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - return paradise; -} - -static int paradise_wd90c30_standalone_available(void) -{ - return rom_present(L"roms/video/wd90c30/90C30-LR.VBI"); -} - -void paradise_close(void *p) -{ - paradise_t *paradise = (paradise_t *)p; - - svga_close(¶dise->svga); - - free(paradise); -} - -void paradise_speed_changed(void *p) -{ - paradise_t *paradise = (paradise_t *)p; - - svga_recalctimings(¶dise->svga); -} - -void paradise_force_redraw(void *p) -{ - paradise_t *paradise = (paradise_t *)p; - - paradise->svga.fullchange = changeframecount; -} - - -const device_t paradise_pvga1a_pc2086_device = -{ - "Paradise PVGA1A (Amstrad PC2086)", - 0, - 0, - paradise_pvga1a_pc2086_init, - paradise_close, - NULL, - NULL, - paradise_speed_changed, - paradise_force_redraw, - NULL -}; -const device_t paradise_pvga1a_pc3086_device = -{ - "Paradise PVGA1A (Amstrad PC3086)", - 0, - 0, - paradise_pvga1a_pc3086_init, - paradise_close, - NULL, - NULL, - paradise_speed_changed, - paradise_force_redraw, - NULL -}; - -static const device_config_t paradise_pvga1a_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 512, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "1 MB", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -const device_t paradise_pvga1a_device = -{ - "Paradise PVGA1A", - DEVICE_ISA, - 0, - paradise_pvga1a_standalone_init, - paradise_close, - NULL, - paradise_pvga1a_standalone_available, - paradise_speed_changed, - paradise_force_redraw, - paradise_pvga1a_config -}; -const device_t paradise_wd90c11_megapc_device = -{ - "Paradise WD90C11 (Amstrad MegaPC)", - 0, - 0, - paradise_wd90c11_megapc_init, - paradise_close, - NULL, - NULL, - paradise_speed_changed, - paradise_force_redraw, - NULL -}; -const device_t paradise_wd90c11_device = -{ - "Paradise WD90C11-LR", - DEVICE_ISA, - 0, - paradise_wd90c11_standalone_init, - paradise_close, - NULL, - paradise_wd90c11_standalone_available, - paradise_speed_changed, - paradise_force_redraw, - NULL -}; - -static const device_config_t paradise_wd90c30_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 1024, - { - { - "512 kB", 512 - }, - { - "1 MB", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -const device_t paradise_wd90c30_device = -{ - "Paradise WD90C30-LR", - DEVICE_ISA, - 0, - paradise_wd90c30_standalone_init, - paradise_close, - NULL, - paradise_wd90c30_standalone_available, - paradise_speed_changed, - paradise_force_redraw, - paradise_wd90c30_config -}; diff --git a/backup code/video - Cópia/vid_paradise.h b/backup code/video - Cópia/vid_paradise.h deleted file mode 100644 index bdc4734aa..000000000 --- a/backup code/video - Cópia/vid_paradise.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -extern const device_t paradise_pvga1a_pc2086_device; -extern const device_t paradise_pvga1a_pc3086_device; -extern const device_t paradise_pvga1a_device; -extern const device_t paradise_wd90c11_megapc_device; -extern const device_t paradise_wd90c11_device; -extern const device_t paradise_wd90c30_device; diff --git a/backup code/video - Cópia/vid_s3.c b/backup code/video - Cópia/vid_s3.c deleted file mode 100644 index 5e358f0ff..000000000 --- a/backup code/video - Cópia/vid_s3.c +++ /dev/null @@ -1,3245 +0,0 @@ -/* - * 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. - * - * S3 emulation. - * - * Version: @(#)vid_s3.c 1.0.10 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../plat.h" -#include "video.h" -#include "vid_s3.h" -#include "vid_svga.h" -#include "vid_svga_render.h" -#include "vid_sdac_ramdac.h" - -enum -{ - S3_VISION864, - S3_TRIO32, - S3_TRIO64 -}; - -enum -{ - VRAM_4MB = 0, - VRAM_8MB = 3, - VRAM_2MB = 4, - VRAM_1MB = 6, - VRAM_512KB = 7 -}; - -#define FIFO_SIZE 65536 -#define FIFO_MASK (FIFO_SIZE - 1) -#define FIFO_ENTRY_SIZE (1 << 31) - -#define FIFO_ENTRIES (s3->fifo_write_idx - s3->fifo_read_idx) -#define FIFO_FULL ((s3->fifo_write_idx - s3->fifo_read_idx) >= FIFO_SIZE) -#define FIFO_EMPTY (s3->fifo_read_idx == s3->fifo_write_idx) - -#define FIFO_TYPE 0xff000000 -#define FIFO_ADDR 0x00ffffff - -enum -{ - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_WORD = (0x02 << 24), - FIFO_WRITE_DWORD = (0x03 << 24), - FIFO_OUT_BYTE = (0x04 << 24), - FIFO_OUT_WORD = (0x05 << 24), - FIFO_OUT_DWORD = (0x06 << 24) -}; - -typedef struct -{ - uint32_t addr_type; - uint32_t val; -} fifo_entry_t; - -typedef struct s3_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t mmio_mapping; - - uint8_t has_bios; - rom_t bios_rom; - - svga_t svga; - sdac_ramdac_t ramdac; - - uint8_t bank; - uint8_t ma_ext; - int width; - int bpp; - - int chip, pci; - - uint8_t id, id_ext, id_ext_pci; - - uint8_t int_line; - - int packed_mmio; - - uint32_t linear_base, linear_size; - - uint8_t pci_regs[256]; - int card; - - uint32_t vram_mask; - uint8_t status_9ae8; - - float (*getclock)(int clock, void *p); - void *getclock_p; - - struct - { - uint16_t subsys_cntl; - uint16_t setup_md; - uint8_t advfunc_cntl; - uint16_t cur_y, cur_y2; - uint16_t cur_x, cur_x2; - uint16_t x2; - int16_t desty_axstp, desty_axstp2; - int16_t destx_distp; - int16_t err_term, err_term2; - int16_t maj_axis_pcnt, maj_axis_pcnt2; - uint16_t cmd; - uint16_t short_stroke; - uint32_t bkgd_color; - uint32_t frgd_color; - uint32_t wrt_mask; - uint32_t rd_mask; - uint32_t color_cmp; - uint8_t bkgd_mix; - uint8_t frgd_mix; - uint16_t multifunc_cntl; - uint16_t multifunc[16]; - uint8_t pix_trans[4]; - - int cx, cy; - int sx, sy; - int dx, dy; - uint32_t src, dest, pattern; - int pix_trans_count; - - int poly_cx, poly_cx2; - int poly_cy, poly_cy2; - int point_1_updated, point_2_updated; - int poly_dx1, poly_dx2; - int poly_x; - - uint32_t dat_buf; - int dat_count; - } accel; - - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; - - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; - - int blitter_busy; - uint64_t blitter_time; - uint64_t status_time; - - uint8_t subsys_cntl, subsys_stat; - - uint32_t hwc_fg_col, hwc_bg_col; - int hwc_col_stack_pos; -} s3_t; - -#define INT_VSY (1 << 0) -#define INT_GE_BSY (1 << 1) -#define INT_FIFO_OVR (1 << 2) -#define INT_FIFO_EMP (1 << 3) -#define INT_MASK 0xf - -void s3_updatemapping(); - -void s3_accel_write(uint32_t addr, uint8_t val, void *p); -void s3_accel_write_w(uint32_t addr, uint16_t val, void *p); -void s3_accel_write_l(uint32_t addr, uint32_t val, void *p); -uint8_t s3_accel_read(uint32_t addr, void *p); - -static inline void wake_fifo_thread(s3_t *s3) -{ - thread_set_event(s3->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ -} - -static void s3_wait_fifo_idle(s3_t *s3) -{ - while (!FIFO_EMPTY) - { - wake_fifo_thread(s3); - thread_wait_event(s3->fifo_not_full_event, 1); - } -} - -static void s3_update_irqs(s3_t *s3) -{ - if (!s3->pci) - { - return; - } - - if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) - pci_set_irq(s3->card, PCI_INTA); - else - pci_clear_irq(s3->card, PCI_INTA); -} - -void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3); - -#define WRITE8(addr, var, val) switch ((addr) & 3) \ - { \ - case 0: var = (var & 0xffffff00) | (val); break; \ - case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \ - case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \ - case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ - } - -static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) -{ - switch (port) - { - case 0x82e8: - s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; - s3->accel.poly_cy = s3->accel.cur_y; - break; - case 0x82e9: - s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x1f) << 8); - s3->accel.poly_cy = s3->accel.cur_y; - break; - case 0x82ea: - s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xf00) | val; - s3->accel.poly_cy2 = s3->accel.cur_y2; - break; - case 0x82eb: - s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xff) | ((val & 0x1f) << 8); - s3->accel.poly_cy2 = s3->accel.cur_y2; - break; - - case 0x86e8: - s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; - s3->accel.poly_cx = s3->accel.cur_x << 20; - s3->accel.poly_x = s3->accel.poly_cx >> 20; - break; - case 0x86e9: - s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x1f) << 8); - s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; - s3->accel.poly_x = s3->accel.poly_cx >> 20; - break; - case 0x86ea: - s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xf00) | val; - s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; - break; - case 0x86eb: - s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xff) | ((val & 0x1f) << 8); - s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; - break; - - case 0x8ae8: - s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val; - s3->accel.point_1_updated = 1; - break; - case 0x8ae9: - s3->accel.desty_axstp = (s3->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.desty_axstp |= ~0x3fff; - s3->accel.point_1_updated = 1; - break; - case 0x8aea: - s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0x3f00) | val; - s3->accel.point_2_updated = 1; - break; - case 0x8aeb: - s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.desty_axstp2 |= ~0x3fff; - s3->accel.point_2_updated = 1; - break; - - case 0x8ee8: - s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val; - s3->accel.point_1_updated = 1; - break; - case 0x8ee9: - s3->accel.destx_distp = (s3->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.destx_distp |= ~0x3fff; - s3->accel.point_1_updated = 1; - break; - case 0x8eea: - s3->accel.x2 = (s3->accel.x2 & 0xf00) | val; - s3->accel.point_2_updated = 1; - break; - case 0x8eeb: - s3->accel.x2 = (s3->accel.x2 & 0xff) | ((val & 0xf) << 8); - s3->accel.point_2_updated = 1; - break; - - case 0x92e8: - s3->accel.err_term = (s3->accel.err_term & 0x3f00) | val; - break; - case 0x92e9: - s3->accel.err_term = (s3->accel.err_term & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.err_term |= ~0x3fff; - break; - case 0x92ea: - s3->accel.err_term2 = (s3->accel.err_term2 & 0x3f00) | val; - break; - case 0x92eb: - s3->accel.err_term2 = (s3->accel.err_term2 & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.err_term2 |= ~0x3fff; - break; - - case 0x96e8: - s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0x3f00) | val; - break; - case 0x96e9: - s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xff) | ((val & 0x0f) << 8); - if (val & 0x08) - s3->accel.maj_axis_pcnt |= ~0x0fff; - break; - case 0x96ea: - s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xf00) | val; - break; - case 0x96eb: - s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xff) | ((val & 0x0f) << 8); - if (val & 0x08) - s3->accel.maj_axis_pcnt2 |= ~0x0fff; - break; - - case 0x9ae8: - s3->accel.cmd = (s3->accel.cmd & 0xff00) | val; - break; - case 0x9ae9: - s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8); - s3_accel_start(-1, 0, 0xffffffff, 0, s3); - s3->accel.pix_trans_count = 0; - s3->accel.multifunc[0xe] &= ~0x10; /*hack*/ - break; - - case 0x9ee8: - s3->accel.short_stroke = (s3->accel.short_stroke & 0xff00) | val; - break; - case 0x9ee9: - s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); - break; - - case 0xa2e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; - break; - case 0xa2e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xa2ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) - { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; - } - break; - case 0xa2eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) - { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; - - case 0xa6e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; - break; - case 0xa6e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xa6ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) - { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; - } - break; - case 0xa6eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) - { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; - - case 0xaae8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; - break; - case 0xaae9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xaaea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) - { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; - } - break; - case 0xaaeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) - { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; - - case 0xaee8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; - break; - case 0xaee9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xaeea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) - { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; - } - break; - case 0xaeeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) - { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; - - case 0xb2e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; - break; - case 0xb2e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xb2ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) - { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; - } - break; - case 0xb2eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) - { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; - - case 0xb6e8: - s3->accel.bkgd_mix = val; - break; - - case 0xbae8: - s3->accel.frgd_mix = val; - break; - - case 0xbee8: - s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff00) | val; - break; - case 0xbee9: - s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff) | (val << 8); - s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff; - break; - - case 0xe2e8: - s3->accel.pix_trans[0] = val; - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100)) - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); - else if (!(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100)) - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - break; - case 0xe2e9: - s3->accel.pix_trans[1] = val; - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100)) - { - if (s3->accel.cmd & 0x1000) s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); - else s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); - } - else if ((s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100)) - { - if (s3->accel.cmd & 0x1000) s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); - else s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } - break; - case 0xe2ea: - s3->accel.pix_trans[2] = val; - break; - case 0xe2eb: - s3->accel.pix_trans[3] = val; - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x600 && (s3->accel.cmd & 0x100) && s3->chip == S3_TRIO32) - { - s3_accel_start(8, 1, s3->accel.pix_trans[3], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[2], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); - } - else if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x400) == 0x400 && (s3->accel.cmd & 0x100)) - s3_accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); - else if ((s3->accel.cmd & 0x600) == 0x400 && (s3->accel.cmd & 0x100)) - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - break; - } -} - -static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) -{ - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) - { - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); - } - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(8, 1, val | (val << 16), 0, s3); - else - s3_accel_start(16, 1, val | (val << 16), 0, s3); - } - else - { - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); - else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } - } -} - -static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) -{ - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(8, 1, (val >> 24) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 16) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); - } - else if (s3->accel.cmd & 0x400) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(32, 1, val, 0, s3); - } - else if ((s3->accel.cmd & 0x600) == 0x200) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(16, 1, val, 0, s3); - s3_accel_start(16, 1, val >> 16, 0, s3); - } - else - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(8, 1, val, 0, s3); - s3_accel_start(8, 1, val >> 16, 0, s3); - } - } - else - { - if (s3->accel.cmd & 0x400) - s3_accel_start(4, 1, 0xffffffff, val, s3); - else if ((s3->accel.cmd & 0x600) == 0x200) - { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); - } - else - { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); - } - } - } -} - -static void s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) -{ - if (s3->packed_mmio) - { - int addr_lo = addr & 1; - switch (addr & 0xfffe) - { - case 0x8100: addr = 0x82e8; break; /*ALT_CURXY*/ - case 0x8102: addr = 0x86e8; break; - - case 0x8104: addr = 0x82ea; break; /*ALT_CURXY2*/ - case 0x8106: addr = 0x86ea; break; - - case 0x8108: addr = 0x8ae8; break; /*ALT_STEP*/ - case 0x810a: addr = 0x8ee8; break; - - case 0x810c: addr = 0x8aea; break; /*ALT_STEP2*/ - case 0x810e: addr = 0x8eea; break; - - case 0x8110: addr = 0x92e8; break; /*ALT_ERR*/ - case 0x8112: addr = 0x92ee; break; - - case 0x8118: addr = 0x9ae8; break; /*ALT_CMD*/ - case 0x811a: addr = 0x9aea; break; - - case 0x811c: addr = 0x9ee8; break; /*SHORT_STROKE*/ - - case 0x8120: case 0x8122: /*BKGD_COLOR*/ - WRITE8(addr, s3->accel.bkgd_color, val); - return; - - case 0x8124: case 0x8126: /*FRGD_COLOR*/ - WRITE8(addr, s3->accel.frgd_color, val); - return; - - case 0x8128: case 0x812a: /*WRT_MASK*/ - WRITE8(addr, s3->accel.wrt_mask, val); - return; - - case 0x812c: case 0x812e: /*RD_MASK*/ - WRITE8(addr, s3->accel.rd_mask, val); - return; - - case 0x8130: case 0x8132: /*COLOR_CMP*/ - WRITE8(addr, s3->accel.color_cmp, val); - return; - - case 0x8134: addr = 0xb6e8; break; /*ALT_MIX*/ - case 0x8136: addr = 0xbae8; break; - - case 0x8138: /*SCISSORS_T*/ - WRITE8(addr & 1, s3->accel.multifunc[1], val); - return; - case 0x813a: /*SCISSORS_L*/ - WRITE8(addr & 1, s3->accel.multifunc[2], val); - return; - case 0x813c: /*SCISSORS_B*/ - WRITE8(addr & 1, s3->accel.multifunc[3], val); - return; - case 0x813e: /*SCISSORS_R*/ - WRITE8(addr & 1, s3->accel.multifunc[4], val); - return; - - case 0x8140: /*PIX_CNTL*/ - WRITE8(addr & 1, s3->accel.multifunc[0xa], val); - return; - case 0x8142: /*MULT_MISC2*/ - WRITE8(addr & 1, s3->accel.multifunc[0xd], val); - return; - case 0x8144: /*MULT_MISC*/ - WRITE8(addr & 1, s3->accel.multifunc[0xe], val); - return; - case 0x8146: /*READ_SEL*/ - WRITE8(addr & 1, s3->accel.multifunc[0xf], val); - return; - - case 0x8148: /*ALT_PCNT*/ - WRITE8(addr & 1, s3->accel.multifunc[0], val); - return; - case 0x814a: addr = 0x96e8; break; - case 0x814c: addr = 0x96ea; break; - - case 0x8168: addr = 0xeae8; break; - case 0x816a: addr = 0xeaea; break; - } - addr |= addr_lo; - } - - - if (addr & 0x8000) - { - s3_accel_out_fifo(s3, addr & 0xffff, val); - } - else - { - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); - } - } -} - -static void s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) -{ - if (addr & 0x8000) - { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - } - else - { - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) - { - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); - } - else if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(8, 1, val | (val << 16), 0, s3); - else - s3_accel_start(16, 1, val | (val << 16), 0, s3); - } - else - { - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); - else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } - } - } -} - -static void s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) -{ - if (addr & 0x8000) - { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - s3_accel_write_fifo(s3, addr + 2, val >> 16); - s3_accel_write_fifo(s3, addr + 3, val >> 24); - } - else - { - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(8, 1, (val >> 24) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 16) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); - } - else if (s3->accel.cmd & 0x400) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(32, 1, val, 0, s3); - } - else if ((s3->accel.cmd & 0x600) == 0x200) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(16, 1, val, 0, s3); - s3_accel_start(16, 1, val >> 16, 0, s3); - } - else - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(8, 1, val, 0, s3); - s3_accel_start(8, 1, val >> 16, 0, s3); - } - } - else - { - if (s3->accel.cmd & 0x400) - s3_accel_start(4, 1, 0xffffffff, val, s3); - else if ((s3->accel.cmd & 0x600) == 0x200) - { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); - } - else - { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); - } - } - } - } -} - -static void fifo_thread(void *param) -{ - s3_t *s3 = (s3_t *)param; - - while (1) - { - thread_set_event(s3->fifo_not_full_event); - thread_wait_event(s3->wake_fifo_thread, -1); - thread_reset_event(s3->wake_fifo_thread); - s3->blitter_busy = 1; - while (!FIFO_EMPTY) - { - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &s3->fifo[s3->fifo_read_idx & FIFO_MASK]; - - switch (fifo->addr_type & FIFO_TYPE) - { - case FIFO_WRITE_BYTE: - s3_accel_write_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_WORD: - s3_accel_write_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_DWORD: - s3_accel_write_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_OUT_BYTE: - s3_accel_out_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_OUT_WORD: - s3_accel_out_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_OUT_DWORD: - s3_accel_out_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - } - - s3->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; - - if (FIFO_ENTRIES > 0xe000) - thread_set_event(s3->fifo_not_full_event); - - end_time = plat_timer_read(); - s3->blitter_time += end_time - start_time; - } - s3->blitter_busy = 0; - s3->subsys_stat |= INT_FIFO_EMP; - s3_update_irqs(s3); - } -} - -static void s3_vblank_start(svga_t *svga) -{ - s3_t *s3 = (s3_t *)svga->p; - - s3->subsys_stat |= INT_VSY; - s3_update_irqs(s3); -} - -static void s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type) -{ - fifo_entry_t *fifo = &s3->fifo[s3->fifo_write_idx & FIFO_MASK]; - - if (FIFO_FULL) - { - thread_reset_event(s3->fifo_not_full_event); - if (FIFO_FULL) - { - thread_wait_event(s3->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } - - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; - - s3->fifo_write_idx++; - - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(s3); -} - -void s3_out(uint16_t addr, uint8_t val, void *p) -{ - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - uint8_t old; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3c5: - if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) - { - svga->seqregs[svga->seqaddr] = val; - switch (svga->seqaddr) - { - case 0x12: case 0x13: - svga_recalctimings(svga); - return; - } - } - if (svga->seqaddr == 4) /*Chain-4 - update banking*/ - { - if (val & 8) - svga->write_bank = svga->read_bank = s3->bank << 16; - else - svga->write_bank = svga->read_bank = s3->bank << 14; - } - break; - - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) - svga_out(addr, val, svga); - else - { - if ((svga->crtc[0x55] & 1) || (svga->crtc[0x43] & 2)) - sdac_ramdac_out((addr & 3) | 4, val, &s3->ramdac, svga); - else - sdac_ramdac_out(addr & 3, val, &s3->ramdac, svga); - } - return; - - case 0x3D4: - svga->crtcreg = val & 0x7f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) return; - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - switch (svga->crtcreg) - { - case 0x31: - s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); - break; - case 0x32: - svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask; - break; - - case 0x50: - switch (svga->crtc[0x50] & 0xc1) - { - case 0x00: s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; break; - case 0x01: s3->width = 1152; break; - case 0x40: s3->width = 640; break; - case 0x80: s3->width = 800; break; - case 0x81: s3->width = 1600; break; - case 0xc0: s3->width = 1280; break; - } - s3->bpp = (svga->crtc[0x50] >> 4) & 3; - break; - case 0x69: - s3->ma_ext = val & 0x1f; - break; - - case 0x35: - s3->bank = (s3->bank & 0x70) | (val & 0xf); - if (svga->chain4) - svga->write_bank = svga->read_bank = s3->bank << 16; - else - svga->write_bank = svga->read_bank = s3->bank << 14; - break; - case 0x51: - s3->bank = (s3->bank & 0x4f) | ((val & 0xc) << 2); - if (svga->chain4) - svga->write_bank = svga->read_bank = s3->bank << 16; - else - svga->write_bank = svga->read_bank = s3->bank << 14; - s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2); - break; - case 0x6a: - s3->bank = val; - if (svga->chain4) - svga->write_bank = svga->read_bank = s3->bank << 16; - else - svga->write_bank = svga->read_bank = s3->bank << 14; - break; - - case 0x3a: - if (val & 0x10) - svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ - break; - - case 0x45: - svga->hwcursor.ena = val & 1; - break; - case 0x48: - svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff; - if (svga->bpp == 32) svga->hwcursor.x >>= 1; - svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff; - svga->hwcursor.xoff = svga->crtc[0x4e] & 63; - svga->hwcursor.yoff = svga->crtc[0x4f] & 63; - svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); - if ((s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) && svga->bpp == 32) - svga->hwcursor.x <<= 1; - break; - - case 0x4a: - switch (s3->hwc_col_stack_pos) - { - case 0: - s3->hwc_fg_col = (s3->hwc_fg_col & 0xffff00) | val; - break; - case 1: - s3->hwc_fg_col = (s3->hwc_fg_col & 0xff00ff) | (val << 8); - break; - case 2: - s3->hwc_fg_col = (s3->hwc_fg_col & 0x00ffff) | (val << 16); - break; - } - s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; - break; - case 0x4b: - switch (s3->hwc_col_stack_pos) - { - case 0: - s3->hwc_bg_col = (s3->hwc_bg_col & 0xffff00) | val; - break; - case 1: - s3->hwc_bg_col = (s3->hwc_bg_col & 0xff00ff) | (val << 8); - break; - case 2: - s3->hwc_bg_col = (s3->hwc_bg_col & 0x00ffff) | (val << 16); - break; - } - s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; - break; - - case 0x53: - case 0x58: case 0x59: case 0x5a: - s3_updatemapping(s3); - break; - - case 0x67: - if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) - { - switch (val >> 4) - { - case 3: svga->bpp = 15; break; - case 5: svga->bpp = 16; break; - case 7: svga->bpp = 24; break; - case 13: svga->bpp = 32; break; - default: svga->bpp = 8; break; - } - } - break; - } - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); -} - -uint8_t s3_in(uint16_t addr, void *p) -{ - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3c1: - if (svga->attraddr > 0x14) - return 0xff; - break; - - case 0x3c5: - if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) - return svga->seqregs[svga->seqaddr]; - break; - - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) - return svga_in(addr, svga); - if ((svga->crtc[0x55] & 1) || (svga->crtc[0x43] & 2)) - return sdac_ramdac_in((addr & 3) | 4, &s3->ramdac, svga); - return sdac_ramdac_in(addr & 3, &s3->ramdac, svga); - - case 0x3d4: - return svga->crtcreg; - case 0x3d5: - switch (svga->crtcreg) - { - case 0x2d: return 0x88; /*Extended chip ID*/ - case 0x2e: return s3->id_ext; /*New chip ID*/ - case 0x2f: return 0; /*Revision level*/ - case 0x30: return s3->id; /*Chip ID*/ - case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); - case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); - case 0x45: s3->hwc_col_stack_pos = 0; break; - case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); - case 0x69: return s3->ma_ext; - case 0x6a: return s3->bank; - } - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); -} - -void s3_recalctimings(svga_t *svga) -{ - s3_t *s3 = (s3_t *)svga->p; - svga->hdisp = svga->hdisp_old; - - svga->ma_latch |= (s3->ma_ext << 16); - if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; - if (svga->crtc[0x5d] & 0x02) - { - svga->hdisp_time += 0x100; - svga->hdisp += 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); - } - if (svga->crtc[0x5e] & 0x01) svga->vtotal += 0x400; - if (svga->crtc[0x5e] & 0x02) svga->dispend += 0x400; - if (svga->crtc[0x5e] & 0x04) svga->vblankstart += 0x400; - if (svga->crtc[0x5e] & 0x10) svga->vsyncstart += 0x400; - if (svga->crtc[0x5e] & 0x40) svga->split += 0x400; - if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; - else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; - if (!svga->rowoffset) svga->rowoffset = 256; - svga->interlace = svga->crtc[0x42] & 0x20; - svga->clock = cpuclock / s3->getclock((svga->miscout >> 2) & 3, s3->getclock_p); - - switch (svga->crtc[0x67] >> 4) - { - case 3: case 5: case 7: - svga->clock /= 2; - break; - } - - svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); - if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) - { - switch (svga->bpp) - { - case 8: - svga->render = svga_render_8bpp_highres; - break; - case 15: - svga->render = svga_render_15bpp_highres; - svga->hdisp /= 2; - break; - case 16: - svga->render = svga_render_16bpp_highres; - svga->hdisp /= 2; - break; - case 24: - svga->render = svga_render_24bpp_highres; - svga->hdisp /= 3; - break; - case 32: - svga->render = svga_render_32bpp_highres; - if (s3->chip != S3_TRIO32 && s3->chip != S3_TRIO64) - svga->hdisp /= 4; - break; - } - } -} - -void s3_updatemapping(s3_t *s3) -{ - svga_t *svga = &s3->svga; - - if (!(s3->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) - { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&s3->linear_mapping); - mem_mapping_disable(&s3->mmio_mapping); - return; - } - - /*Banked framebuffer*/ - if (svga->crtc[0x31] & 0x08) /*Enhanced mode mappings*/ - { - /* Enhanced mode forces 64kb at 0xa0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - } - else switch (svga->gdcreg[6] & 0xc) /*VGA mapping*/ - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - - if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/ - { - mem_mapping_disable(&svga->mapping); - - s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - switch (svga->crtc[0x58] & 3) - { - case 0: /*64k*/ - s3->linear_size = 0x10000; - break; - case 1: /*1mb*/ - s3->linear_size = 0x100000; - break; - case 2: /*2mb*/ - s3->linear_size = 0x200000; - break; - case 3: /*8mb*/ - s3->linear_size = 0x800000; - break; - } - s3->linear_base &= ~(s3->linear_size - 1); - if (s3->linear_base == 0xa0000) - { - mem_mapping_disable(&s3->linear_mapping); - if (!(svga->crtc[0x53] & 0x10)) - { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - } - } - else - mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); - } - else - mem_mapping_disable(&s3->linear_mapping); - - if (svga->crtc[0x53] & 0x10) /*Memory mapped IO*/ - { - mem_mapping_disable(&svga->mapping); - mem_mapping_enable(&s3->mmio_mapping); - } - else - mem_mapping_disable(&s3->mmio_mapping); -} - -static float s3_trio64_getclock(int clock, void *p) -{ - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - float t; - int m, n1, n2; - if (clock == 0) return 25175000.0; - if (clock == 1) return 28322000.0; - m = svga->seqregs[0x13] + 2; - n1 = (svga->seqregs[0x12] & 0x1f) + 2; - n2 = ((svga->seqregs[0x12] >> 5) & 0x07); - t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); - return t; -} - - -void s3_accel_out(uint16_t port, uint8_t val, void *p) -{ - s3_t *s3 = (s3_t *)p; - - if (port >= 0x8000) - { - s3_queue(s3, port, val, FIFO_OUT_BYTE); - } - else switch (port) - { - case 0x42e8: - s3->subsys_stat &= ~val; - s3_update_irqs(s3); - break; - case 0x42e9: - s3->subsys_cntl = val; - s3_update_irqs(s3); - break; - case 0x46e8: - s3->accel.setup_md = val; - break; - case 0x4ae8: - s3->accel.advfunc_cntl = val; - break; - } -} - -void s3_accel_out_w(uint16_t port, uint16_t val, void *p) -{ - s3_t *s3 = (s3_t *)p; - s3_queue(s3, port, val, FIFO_OUT_WORD); -} - -void s3_accel_out_l(uint16_t port, uint32_t val, void *p) -{ - s3_t *s3 = (s3_t *)p; - s3_queue(s3, port, val, FIFO_OUT_DWORD); -} - -uint8_t s3_accel_in(uint16_t port, void *p) -{ - s3_t *s3 = (s3_t *)p; - int temp; - switch (port) - { - case 0x42e8: - return s3->subsys_stat; - case 0x42e9: - return s3->subsys_cntl; - - case 0x82e8: - s3_wait_fifo_idle(s3); - return s3->accel.cur_y & 0xff; - case 0x82e9: - s3_wait_fifo_idle(s3); - return s3->accel.cur_y >> 8; - - case 0x86e8: - s3_wait_fifo_idle(s3); - return s3->accel.cur_x & 0xff; - case 0x86e9: - s3_wait_fifo_idle(s3); - return s3->accel.cur_x >> 8; - - case 0x8ae8: - s3_wait_fifo_idle(s3); - return s3->accel.desty_axstp & 0xff; - case 0x8ae9: - s3_wait_fifo_idle(s3); - return s3->accel.desty_axstp >> 8; - - case 0x8ee8: - s3_wait_fifo_idle(s3); - return s3->accel.destx_distp & 0xff; - case 0x8ee9: - s3_wait_fifo_idle(s3); - return s3->accel.destx_distp >> 8; - - case 0x92e8: - s3_wait_fifo_idle(s3); - return s3->accel.err_term & 0xff; - case 0x92e9: - s3_wait_fifo_idle(s3); - return s3->accel.err_term >> 8; - - case 0x96e8: - s3_wait_fifo_idle(s3); - return s3->accel.maj_axis_pcnt & 0xff; - case 0x96e9: - s3_wait_fifo_idle(s3); - return s3->accel.maj_axis_pcnt >> 8; - - case 0x9ae8: - if (!s3->blitter_busy) - wake_fifo_thread(s3); - if (FIFO_FULL) - return 0xff; /*FIFO full*/ - return 0; /*FIFO empty*/ - case 0x9ae9: - if (!s3->blitter_busy) - wake_fifo_thread(s3); - temp = 0; - if (!FIFO_EMPTY) - temp |= 0x02; /*Hardware busy*/ - else - temp |= s3->status_9ae8; /*FIFO empty*/ - if (FIFO_FULL) - temp |= 0xf8; /*FIFO full*/ - return temp; - - case 0xa2e8: - s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color & 0xff; - case 0xa2e9: - s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 8; - case 0xa2ea: - s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 16; - case 0xa2eb: - s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 24; - - case 0xa6e8: - s3_wait_fifo_idle(s3); - return s3->accel.frgd_color & 0xff; - case 0xa6e9: - s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 8; - case 0xa6ea: - s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 16; - case 0xa6eb: - s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 24; - - case 0xaae8: - s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask & 0xff; - case 0xaae9: - s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 8; - case 0xaaea: - s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 16; - case 0xaaeb: - s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 24; - - case 0xaee8: - s3_wait_fifo_idle(s3); - return s3->accel.rd_mask & 0xff; - case 0xaee9: - s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 8; - case 0xaeea: - s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 16; - case 0xaeeb: - s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 24; - - case 0xb2e8: - s3_wait_fifo_idle(s3); - return s3->accel.color_cmp & 0xff; - case 0xb2e9: - s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 8; - case 0xb2ea: - s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 16; - case 0xb2eb: - s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 24; - - case 0xb6e8: - s3_wait_fifo_idle(s3); - return s3->accel.bkgd_mix; - - case 0xbae8: - s3_wait_fifo_idle(s3); - return s3->accel.frgd_mix; - - case 0xbee8: - s3_wait_fifo_idle(s3); - temp = s3->accel.multifunc[0xf] & 0xf; - switch (temp) - { - case 0x0: return s3->accel.multifunc[0x0] & 0xff; - case 0x1: return s3->accel.multifunc[0x1] & 0xff; - case 0x2: return s3->accel.multifunc[0x2] & 0xff; - case 0x3: return s3->accel.multifunc[0x3] & 0xff; - case 0x4: return s3->accel.multifunc[0x4] & 0xff; - case 0x5: return s3->accel.multifunc[0xa] & 0xff; - case 0x6: return s3->accel.multifunc[0xe] & 0xff; - case 0x7: return s3->accel.cmd & 0xff; - case 0x8: return s3->accel.subsys_cntl & 0xff; - case 0x9: return s3->accel.setup_md & 0xff; - case 0xa: return s3->accel.multifunc[0xd] & 0xff; - } - return 0xff; - case 0xbee9: - s3_wait_fifo_idle(s3); - temp = s3->accel.multifunc[0xf] & 0xf; - s3->accel.multifunc[0xf]++; - switch (temp) - { - case 0x0: return s3->accel.multifunc[0x0] >> 8; - case 0x1: return s3->accel.multifunc[0x1] >> 8; - case 0x2: return s3->accel.multifunc[0x2] >> 8; - case 0x3: return s3->accel.multifunc[0x3] >> 8; - case 0x4: return s3->accel.multifunc[0x4] >> 8; - case 0x5: return s3->accel.multifunc[0xa] >> 8; - case 0x6: return s3->accel.multifunc[0xe] >> 8; - case 0x7: return s3->accel.cmd >> 8; - case 0x8: return (s3->accel.subsys_cntl >> 8) & ~0xe000; - case 0x9: return (s3->accel.setup_md >> 8) & ~0xf000; - case 0xa: return s3->accel.multifunc[0xd] >> 8; - } - return 0xff; - - case 0xe2e8: case 0xe2e9: case 0xe2ea: case 0xe2eb: /*PIX_TRANS*/ - break; - } - return 0; -} - -void s3_accel_write(uint32_t addr, uint8_t val, void *p) -{ - s3_t *s3 = (s3_t *)p; - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_BYTE); -} -void s3_accel_write_w(uint32_t addr, uint16_t val, void *p) -{ - s3_t *s3 = (s3_t *)p; - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_WORD); -} -void s3_accel_write_l(uint32_t addr, uint32_t val, void *p) -{ - s3_t *s3 = (s3_t *)p; - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_DWORD); -} - -uint8_t s3_accel_read(uint32_t addr, void *p) -{ - if (addr & 0x8000) - return s3_accel_in(addr & 0xffff, p); - return 0; -} - -static void polygon_setup(s3_t *s3) -{ - if (s3->accel.point_1_updated) - { - int start_x = s3->accel.poly_cx; - int start_y = s3->accel.poly_cy; - int end_x = s3->accel.destx_distp << 20; - int end_y = s3->accel.desty_axstp; - - if (end_y - start_y) - s3->accel.poly_dx1 = (end_x - start_x) / (end_y - start_y); - else - s3->accel.poly_dx1 = 0; - - s3->accel.point_1_updated = 0; - - if (end_y == s3->accel.poly_cy) - { - s3->accel.poly_cx = end_x; - s3->accel.poly_x = end_x >> 20; - } - } - if (s3->accel.point_2_updated) - { - int start_x = s3->accel.poly_cx2; - int start_y = s3->accel.poly_cy2; - int end_x = s3->accel.x2 << 20; - int end_y = s3->accel.desty_axstp2; - - if (end_y - start_y) - s3->accel.poly_dx2 = (end_x - start_x) / (end_y - start_y); - else - s3->accel.poly_dx2 = 0; - - s3->accel.point_2_updated = 0; - - if (end_y == s3->accel.poly_cy) - s3->accel.poly_cx2 = end_x; - } -} - -#define READ_SRC(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \ - else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \ - else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; \ - if (vram_mask) \ - dat = ((dat & rd_mask) == rd_mask); - -#define READ_DST(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \ - else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \ - else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; - -#define MIX { \ - uint32_t old_dest_dat = dest_dat; \ - switch ((mix_dat & mix_mask) ? (s3->accel.frgd_mix & 0xf) : (s3->accel.bkgd_mix & 0xf)) \ - { \ - case 0x0: dest_dat = ~dest_dat; break; \ - case 0x1: dest_dat = 0; break; \ - case 0x2: dest_dat = ~0; break; \ - case 0x3: dest_dat = dest_dat; break; \ - case 0x4: dest_dat = ~src_dat; break; \ - case 0x5: dest_dat = src_dat ^ dest_dat; break; \ - case 0x6: dest_dat = ~(src_dat ^ dest_dat); break; \ - case 0x7: dest_dat = src_dat; break; \ - case 0x8: dest_dat = ~(src_dat & dest_dat); break; \ - case 0x9: dest_dat = ~src_dat | dest_dat; break; \ - case 0xa: dest_dat = src_dat | ~dest_dat; break; \ - case 0xb: dest_dat = src_dat | dest_dat; break; \ - case 0xc: dest_dat = src_dat & dest_dat; break; \ - case 0xd: dest_dat = src_dat & ~dest_dat; break; \ - case 0xe: dest_dat = ~src_dat & dest_dat; break; \ - case 0xf: dest_dat = ~(src_dat | dest_dat); break; \ - } \ - dest_dat = (dest_dat & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ - } - - -#define WRITE(addr) if (s3->bpp == 0) \ - { \ - svga->vram[(addr) & s3->vram_mask] = dest_dat; \ - svga->changedvram[((addr) & s3->vram_mask) >> 12] = changeframecount; \ - } \ - else if (s3->bpp == 1) \ - { \ - vram_w[(addr) & (s3->vram_mask >> 1)] = dest_dat; \ - svga->changedvram[((addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \ - } \ - else \ - { \ - vram_l[(addr) & (s3->vram_mask >> 2)] = dest_dat; \ - svga->changedvram[((addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \ - } - -void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3) -{ - svga_t *svga = &s3->svga; - uint32_t src_dat = 0, dest_dat; - int frgd_mix, bkgd_mix; - int clip_t = s3->accel.multifunc[1] & 0xfff; - int clip_l = s3->accel.multifunc[2] & 0xfff; - int clip_b = s3->accel.multifunc[3] & 0xfff; - int clip_r = s3->accel.multifunc[4] & 0xfff; - int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; - uint32_t mix_mask = 0; - uint16_t *vram_w = (uint16_t *)svga->vram; - uint32_t *vram_l = (uint32_t *)svga->vram; - uint32_t compare = s3->accel.color_cmp; - int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; - uint32_t rd_mask = s3->accel.rd_mask; - int cmd = s3->accel.cmd >> 13; - - if ((s3->chip == S3_TRIO64) && (s3->accel.cmd & (1 << 11))) - cmd |= 8; - - if (!cpu_input) s3->accel.dat_count = 0; - if (cpu_input && (s3->accel.multifunc[0xa] & 0xc0) != 0x80) - { - if (s3->bpp == 3 && count == 2) - { - if (s3->accel.dat_count) - { - cpu_dat = ((cpu_dat & 0xffff) << 16) | s3->accel.dat_buf; - count = 4; - s3->accel.dat_count = 0; - } - else - { - s3->accel.dat_buf = cpu_dat & 0xffff; - s3->accel.dat_count = 1; - } - } - if (s3->bpp == 1) count >>= 1; - if (s3->bpp == 3) count >>= 2; - } - - if (s3->bpp == 0) - rd_mask &= 0xff; - else if (s3->bpp == 1) - rd_mask &= 0xffff; - - switch (s3->accel.cmd & 0x600) - { - case 0x000: mix_mask = 0x80; break; - case 0x200: mix_mask = 0x8000; break; - case 0x400: mix_mask = 0x80000000; break; - case 0x600: mix_mask = (s3->chip == S3_TRIO32) ? 0x80 : 0x80000000; break; - } - - if (s3->bpp == 0) compare &= 0xff; - if (s3->bpp == 1) compare &= 0xffff; - switch (cmd) - { - case 1: /*Draw line*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; - - s3->accel.sy = s3->accel.maj_axis_pcnt; - } - - s3->status_9ae8 = 4; /*To avoid the spam from OS/2's drivers*/ - - if ((s3->accel.cmd & 0x100) && !cpu_input) - { - s3->status_9ae8 = 2; /*To avoid the spam from OS/2's drivers*/ - return; /*Wait for data from CPU*/ - } - - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (s3->accel.cmd & 8) /*Radial*/ - { - while (count-- && s3->accel.sy >= 0) - { - if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && - s3->accel.cy >= clip_t && s3->accel.cy <= clip_b) - { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: src_dat = 0; break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) - { - READ_DST((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - - MIX - - WRITE((s3->accel.cy * s3->width) + s3->accel.cx); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; - if (!s3->accel.sy) - break; - - switch (s3->accel.cmd & 0xe0) - { - case 0x00: s3->accel.cx++; break; - case 0x20: s3->accel.cx++; s3->accel.cy--; break; - case 0x40: s3->accel.cy--; break; - case 0x60: s3->accel.cx--; s3->accel.cy--; break; - case 0x80: s3->accel.cx--; break; - case 0xa0: s3->accel.cx--; s3->accel.cy++; break; - case 0xc0: s3->accel.cy++; break; - case 0xe0: s3->accel.cx++; s3->accel.cy++; break; - } - s3->accel.sy--; - } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - } - else /*Bresenham*/ - { - while (count-- && s3->accel.sy >= 0) - { - if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && - s3->accel.cy >= clip_t && s3->accel.cy <= clip_b) - { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: src_dat = 0; break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) - { - READ_DST((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - - MIX - - WRITE((s3->accel.cy * s3->width) + s3->accel.cx); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; - - if (!s3->accel.sy) - break; - - if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) - { - s3->accel.err_term += s3->accel.destx_distp; - /*Step minor axis*/ - switch (s3->accel.cmd & 0xe0) - { - case 0x00: s3->accel.cy--; break; - case 0x20: s3->accel.cy--; break; - case 0x40: s3->accel.cx--; break; - case 0x60: s3->accel.cx++; break; - case 0x80: s3->accel.cy++; break; - case 0xa0: s3->accel.cy++; break; - case 0xc0: s3->accel.cx--; break; - case 0xe0: s3->accel.cx++; break; - } - } - else - s3->accel.err_term += s3->accel.desty_axstp; - - /*Step major axis*/ - switch (s3->accel.cmd & 0xe0) - { - case 0x00: s3->accel.cx--; break; - case 0x20: s3->accel.cx++; break; - case 0x40: s3->accel.cy--; break; - case 0x60: s3->accel.cy--; break; - case 0x80: s3->accel.cx--; break; - case 0xa0: s3->accel.cx++; break; - case 0xc0: s3->accel.cy++; break; - case 0xe0: s3->accel.cy++; break; - } - s3->accel.sy--; - } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - } - break; - - case 2: /*Rectangle fill*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; - - s3->accel.dest = s3->accel.cy * s3->width; - } - - s3->status_9ae8 = 4; /*To avoid the spam from OS/2's drivers*/ - - if ((s3->accel.cmd & 0x100) && !cpu_input) - { - s3->status_9ae8 = 2; /*To avoid the spam from OS/2's drivers*/ - return; /*Wait for data from CPU*/ - } - - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - while (count-- && s3->accel.sy >= 0) - { - if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && - s3->accel.cy >= clip_t && s3->accel.cy <= clip_b) - { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: src_dat = 0; break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) - { - READ_DST(s3->accel.dest + s3->accel.cx, dest_dat); - - MIX - - WRITE(s3->accel.dest + s3->accel.cx); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; - - if (s3->accel.cmd & 0x20) s3->accel.cx++; - else s3->accel.cx--; - s3->accel.sx--; - if (s3->accel.sx < 0) - { - if (s3->accel.cmd & 0x20) s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - else s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - if (s3->accel.cmd & 0x80) s3->accel.cy++; - else s3->accel.cy--; - - s3->accel.dest = s3->accel.cy * s3->width; - s3->accel.sy--; - - if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return; - if (s3->accel.sy < 0) - { - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - return; - } - } - } - break; - - case 6: /*BitBlt*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - - s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.destx_distp & 0x1000) s3->accel.dx |= ~0xfff; - s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; - - s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; - - s3->accel.src = s3->accel.cy * s3->width; - s3->accel.dest = s3->accel.dy * s3->width; - } - - s3->status_9ae8 = 4; /*To avoid the spam from OS/2's drivers*/ - - if ((s3->accel.cmd & 0x100) && !cpu_input) - { - s3->status_9ae8 = 2; /*To avoid the spam from OS/2's drivers*/ - return; /*Wait for data from CPU*/ - } - - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - - if (s3->accel.sy < 0) - return; - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode && - (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7 && - (s3->accel.bkgd_mix & 0xf) == 7) - { - while (1) - { - if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && - s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) - { - READ_SRC(s3->accel.src + s3->accel.cx, src_dat); - READ_DST(s3->accel.dest + s3->accel.dx, dest_dat); - - dest_dat = (src_dat & s3->accel.wrt_mask) | (dest_dat & ~s3->accel.wrt_mask); - - WRITE(s3->accel.dest + s3->accel.dx); - } - - s3->accel.cx++; - s3->accel.dx++; - s3->accel.sx--; - if (s3->accel.sx < 0) - { - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - s3->accel.cy++; - s3->accel.dy++; - - s3->accel.src = s3->accel.cy * s3->width; - s3->accel.dest = s3->accel.dy * s3->width; - - s3->accel.sy--; - - if (s3->accel.sy < 0) - { - return; - } - } - } - } - else - { - while (count-- && s3->accel.sy >= 0) - { - if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && - s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) - { - if (vram_mask) - { - READ_SRC(s3->accel.src + s3->accel.cx, mix_dat) - mix_dat = mix_dat ? mix_mask : 0; - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: READ_SRC(s3->accel.src + s3->accel.cx, src_dat); break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) - { - READ_DST(s3->accel.dest + s3->accel.dx, dest_dat); - - MIX - - WRITE(s3->accel.dest + s3->accel.dx); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; - - if (s3->accel.cmd & 0x20) - { - s3->accel.cx++; - s3->accel.dx++; - } - else - { - s3->accel.cx--; - s3->accel.dx--; - } - s3->accel.sx--; - if (s3->accel.sx < 0) - { - if (s3->accel.cmd & 0x20) - { - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } - else - { - s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - if (s3->accel.cmd & 0x80) - { - s3->accel.cy++; - s3->accel.dy++; - } - else - { - s3->accel.cy--; - s3->accel.dy--; - } - - s3->accel.src = s3->accel.cy * s3->width; - s3->accel.dest = s3->accel.dy * s3->width; - - s3->accel.sy--; - - if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return; - if (s3->accel.sy < 0) - { - return; - } - } - } - } - break; - - case 7: /*Pattern fill - BitBlt but with source limited to 8x8*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - - s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.destx_distp & 0x1000) s3->accel.dx |= ~0xfff; - s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; - - s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x & 0x1000) s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; - - /*Align source with destination*/ - s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; - s3->accel.dest = s3->accel.dy * s3->width; - - s3->accel.cx = s3->accel.dx & 7; - s3->accel.cy = s3->accel.dy & 7; - - s3->accel.src = s3->accel.pattern + (s3->accel.cy * s3->width); - } - - s3->status_9ae8 = 4; /*To avoid the spam from OS/2's drivers*/ - - if ((s3->accel.cmd & 0x100) && !cpu_input) - { - s3->status_9ae8 = 2; /*To avoid the spam from OS/2's drivers*/ - return; /*Wait for data from CPU*/ - } - - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - while (count-- && s3->accel.sy >= 0) - { - if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && - s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) - { - if (vram_mask) - { - READ_SRC(s3->accel.src + s3->accel.cx, mix_dat) - mix_dat = mix_dat ? mix_mask : 0; - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: READ_SRC(s3->accel.src + s3->accel.cx, src_dat); break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) - { - READ_DST(s3->accel.dest + s3->accel.dx, dest_dat); - - MIX - - WRITE(s3->accel.dest + s3->accel.dx); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; - - if (s3->accel.cmd & 0x20) - { - s3->accel.cx = ((s3->accel.cx + 1) & 7) | (s3->accel.cx & ~7); - s3->accel.dx++; - } - else - { - s3->accel.cx = ((s3->accel.cx - 1) & 7) | (s3->accel.cx & ~7); - s3->accel.dx--; - } - s3->accel.sx--; - if (s3->accel.sx < 0) - { - if (s3->accel.cmd & 0x20) - { - s3->accel.cx = ((s3->accel.cx - ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7); - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } - else - { - s3->accel.cx = ((s3->accel.cx + ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7); - s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - if (s3->accel.cmd & 0x80) - { - s3->accel.cy = ((s3->accel.cy + 1) & 7) | (s3->accel.cy & ~7); - s3->accel.dy++; - } - else - { - s3->accel.cy = ((s3->accel.cy - 1) & 7) | (s3->accel.cy & ~7); - s3->accel.dy--; - } - - s3->accel.src = s3->accel.pattern + (s3->accel.cy * s3->width); - s3->accel.dest = s3->accel.dy * s3->width; - - s3->accel.sy--; - - if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return; - if (s3->accel.sy < 0) - return; - } - } - break; - - case 3: /*Polygon Fill Solid (Trio64 only)*/ - { - int end_y1, end_y2; - - if (s3->chip != S3_TRIO64) - break; - - polygon_setup(s3); - - s3->status_9ae8 = 4; /*To avoid the spam from OS/2's drivers*/ - - if ((s3->accel.cmd & 0x100) && !cpu_input) - { - s3->status_9ae8 = 2; /*To avoid the spam from OS/2's drivers*/ - return; /*Wait for data from CPU*/ - } - - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - - end_y1 = s3->accel.desty_axstp; - end_y2 = s3->accel.desty_axstp2; - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - - while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) - { - int y = s3->accel.poly_cy; - int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; - - s3->accel.dest = y * s3->width; - - while (x_count-- && count--) - { - if (s3->accel.poly_x >= clip_l && s3->accel.poly_x <= clip_r && - s3->accel.poly_cy >= clip_t && s3->accel.poly_cy <= clip_b) - { - switch (frgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: src_dat = 0; /*Nor supported?*/ break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) - { - READ_DST(s3->accel.dest + s3->accel.poly_x, dest_dat); - - MIX - - WRITE(s3->accel.dest + s3->accel.poly_x); - } - } - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; - - if (s3->accel.poly_x < (s3->accel.poly_cx2 >> 20)) - s3->accel.poly_x++; - else - s3->accel.poly_x--; - } - - s3->accel.poly_cx += s3->accel.poly_dx1; - s3->accel.poly_cx2 += s3->accel.poly_dx2; - s3->accel.poly_x = s3->accel.poly_cx >> 20; - - s3->accel.poly_cy++; - s3->accel.poly_cy2++; - - if (!count) - break; - } - - s3->accel.cur_x = s3->accel.poly_cx & 0xfff; - s3->accel.cur_y = s3->accel.poly_cy & 0xfff; - s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff; - s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff; - } - break; - - case 11: /*Polygon Fill Pattern (Trio64 only)*/ - { - int end_y1, end_y2; - - if (s3->chip != S3_TRIO64) - break; - - polygon_setup(s3); - - s3->status_9ae8 = 4; /*To avoid the spam from OS/2's drivers*/ - - if ((s3->accel.cmd & 0x100) && !cpu_input) - { - s3->status_9ae8 = 2; /*To avoid the spam from OS/2's drivers*/ - return; /*Wait for data from CPU*/ - } - - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - - end_y1 = s3->accel.desty_axstp; - end_y2 = s3->accel.desty_axstp2; - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) - { - int y = s3->accel.poly_cy; - int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; - - s3->accel.src = s3->accel.pattern + ((y & 7) * s3->width); - s3->accel.dest = y * s3->width; - - while (x_count-- && count--) - { - int pat_x = s3->accel.poly_x & 7; - - if (s3->accel.poly_x >= clip_l && s3->accel.poly_x <= clip_r && - s3->accel.poly_cy >= clip_t && s3->accel.poly_cy <= clip_b) - { - if (vram_mask) - { - READ_SRC(s3->accel.src + pat_x, mix_dat) - mix_dat = mix_dat ? mix_mask : 0; - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: READ_SRC(s3->accel.src + pat_x, src_dat); break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) - { - READ_DST(s3->accel.dest + s3->accel.poly_x, dest_dat); - - MIX - - WRITE(s3->accel.dest + s3->accel.poly_x); - } - } - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; - - mix_dat <<= 1; - mix_dat |= 1; - - if (s3->accel.poly_x < (s3->accel.poly_cx2 >> 20)) - s3->accel.poly_x++; - else - s3->accel.poly_x--; - } - - s3->accel.poly_cx += s3->accel.poly_dx1; - s3->accel.poly_cx2 += s3->accel.poly_dx2; - s3->accel.poly_x = s3->accel.poly_cx >> 20; - - s3->accel.poly_cy++; - s3->accel.poly_cy2++; - - if (!count) - break; - } - - s3->accel.cur_x = s3->accel.poly_cx & 0xfff; - s3->accel.cur_y = s3->accel.poly_cy & 0xfff; - s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff; - s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff; - } - break; - } -} - -void s3_hwcursor_draw(svga_t *svga, int displine) -{ - s3_t *s3 = (s3_t *)svga->p; - int x; - uint16_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - - uint32_t fg = 0, bg = 0; - - switch (svga->bpp) - { - case 15: - fg = video_15to32[s3->hwc_fg_col & 0xffff]; - bg = video_15to32[s3->hwc_bg_col & 0xffff]; - break; - - case 16: - fg = video_16to32[s3->hwc_fg_col & 0xffff]; - bg = video_16to32[s3->hwc_bg_col & 0xffff]; - break; - - case 24: case 32: - fg = s3->hwc_fg_col; - bg = s3->hwc_bg_col; - break; - - default: - if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) - { - fg = svga->pallook[s3->hwc_fg_col & 0xff]; - bg = svga->pallook[s3->hwc_bg_col & 0xff]; - } - else - { - fg = svga->pallook[svga->crtc[0xe]]; - bg = svga->pallook[svga->crtc[0xf]]; - } - break; - } - - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; - - for (x = 0; x < 64; x += 16) - { - dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; - dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; - for (xx = 0; xx < 16; xx++) - { - if (offset >= svga->hwcursor_latch.x) - { - if (!(dat[0] & 0x8000)) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = (dat[1] & 0x8000) ? fg : bg; - else if (dat[1] & 0x8000) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; - } - - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - svga->hwcursor_latch.addr += 4; - } - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; -} - - -static void s3_io_remove(s3_t *s3) -{ - io_removehandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); - - io_removehandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - if (s3->chip == S3_TRIO64) - { - io_sethandler(0x82e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x86e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x92e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x96e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - } - else - { - io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - } - io_removehandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); -} - -static void s3_io_set(s3_t *s3) -{ - s3_io_remove(s3); - - io_sethandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); - - io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); -} - - -uint8_t s3_pci_read(int func, int addr, void *p) -{ - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - switch (addr) - { - case 0x00: return 0x33; /*'S3'*/ - case 0x01: return 0x53; - - case 0x02: return s3->id_ext_pci; - case 0x03: return 0x88; - - case PCI_REG_COMMAND: - return s3->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - - case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ - - case 0x08: return 0; /*Revision ID*/ - case 0x09: return 0; /*Programming interface*/ - - case 0x0a: return 0x00; /*Supports VGA interface*/ - case 0x0b: return 0x03; - - case 0x10: return 0x00; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: return svga->crtc[0x5a] & 0x80; - case 0x13: return svga->crtc[0x59]; - - case 0x30: return s3->has_bios ? (s3->pci_regs[0x30] & 0x01) : 0x00; /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return s3->has_bios ? s3->pci_regs[0x32] : 0x00; - case 0x33: return s3->has_bios ? s3->pci_regs[0x33] : 0x00; - - case 0x3c: return s3->int_line; - case 0x3d: return PCI_INTA; - } - return 0; -} - -void s3_pci_write(int func, int addr, uint8_t val, void *p) -{ - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - switch (addr) - { - case PCI_REG_COMMAND: - s3->pci_regs[PCI_REG_COMMAND] = val & 0x23; - if (val & PCI_COMMAND_IO) - s3_io_set(s3); - else - s3_io_remove(s3); - s3_updatemapping(s3); - break; - - case 0x12: - svga->crtc[0x5a] = val & 0x80; - s3_updatemapping(s3); - break; - case 0x13: - svga->crtc[0x59] = val; - s3_updatemapping(s3); - break; - - case 0x30: case 0x32: case 0x33: - if (!s3->has_bios) - return; - s3->pci_regs[addr] = val; - if (s3->pci_regs[0x30] & 0x01) - { - uint32_t addr = (s3->pci_regs[0x32] << 16) | (s3->pci_regs[0x33] << 24); - mem_mapping_set_addr(&s3->bios_rom.mapping, addr, 0x8000); - } - else - { - mem_mapping_disable(&s3->bios_rom.mapping); - } - return; - - case 0x3c: - s3->int_line = val; - return; - } -} - -static int vram_sizes[] = -{ - 7, /*512 kB*/ - 6, /*1 MB*/ - 4, /*2 MB*/ - 0, - 0, /*4 MB*/ - 0, - 0, - 0, - 3 /*8 MB*/ -}; - -static void *s3_init(const device_t *info, wchar_t *bios_fn, int chip) -{ - s3_t *s3 = malloc(sizeof(s3_t)); - svga_t *svga = &s3->svga; - int vram; - uint32_t vram_size; - - memset(s3, 0, sizeof(s3_t)); - - vram = device_get_config_int("memory"); - if (vram) - vram_size = vram << 20; - else - vram_size = 512 << 10; - s3->vram_mask = vram_size - 1; - - s3->has_bios = !info->local; - if (s3->has_bios) { - rom_init(&s3->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (info->flags & DEVICE_PCI) - mem_mapping_disable(&s3->bios_rom.mapping); - } - - s3->pci = !!(info->flags & DEVICE_PCI); - - mem_mapping_add(&s3->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, &s3->svga); - mem_mapping_add(&s3->mmio_mapping, 0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, NULL, MEM_MAPPING_EXTERNAL, s3); - mem_mapping_disable(&s3->mmio_mapping); - - svga_init(&s3->svga, s3, vram_size, /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/ - s3_recalctimings, - s3_in, s3_out, - s3_hwcursor_draw, - NULL); - - svga->decode_mask = (4 << 20) - 1; - switch (vram) - { - case 0: /*512kb*/ - svga->vram_mask = (1 << 19) - 1; - svga->vram_max = 2 << 20; - break; - case 1: /*1MB*/ - /*VRAM in first MB, mirrored in 2nd MB, 3rd and 4th MBs are open bus*/ - /*This works with the #9 9FX BIOS, and matches how my real Trio64 behaves, - but does not work with the Phoenix EDO BIOS. Possibly an FPM/EDO difference?*/ - svga->vram_mask = (1 << 20) - 1; - svga->vram_max = 2 << 20; - break; - case 2: default: /*2MB*/ - /*VRAM in first 2 MB, 3rd and 4th MBs are open bus*/ - svga->vram_mask = (2 << 20) - 1; - svga->vram_max = 2 << 20; - break; - case 4: /*4MB*/ - svga->vram_mask = (4 << 20) - 1; - svga->vram_max = 4 << 20; - break; - case 8: /*4MB*/ - svga->vram_mask = (8 << 20) - 1; - svga->vram_max = 8 << 20; - break; - } - - if (info->flags & DEVICE_PCI) - svga->crtc[0x36] = 2 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); - else - svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); - svga->crtc[0x37] = 1 | (7 << 5); - - svga->vblank_start = s3_vblank_start; - - s3_io_set(s3); - - if (info->flags & DEVICE_PCI) - { - s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); - } - - s3->pci_regs[0x04] = 7; - - s3->pci_regs[0x30] = 0x00; - s3->pci_regs[0x32] = 0x0c; - s3->pci_regs[0x33] = 0x00; - - s3->chip = chip; - - s3->wake_fifo_thread = thread_create_event(); - s3->fifo_not_full_event = thread_create_event(); - s3->fifo_thread = thread_create(fifo_thread, s3); - - s3->int_line = 0; - - return s3; -} - -void *s3_vision864_init(const device_t *info, wchar_t *bios_fn) -{ - s3_t *s3 = s3_init(info, bios_fn, S3_VISION864); - - s3->id = 0xc1; /*Vision864P*/ - s3->id_ext = s3->id_ext_pci = 0xc1; - s3->packed_mmio = 0; - - s3->getclock = sdac_getclock; - s3->getclock_p = &s3->ramdac; - sdac_init(&s3->ramdac); - - return s3; -} - - -static void *s3_bahamas64_init(const device_t *info) -{ - s3_t *s3 = s3_vision864_init(info, L"roms/video/s3/bahamas64.bin"); - return s3; -} - -static void *s3_phoenix_vision864_init(const device_t *info) -{ - s3_t *s3 = s3_vision864_init(info, L"roms/video/s3/86c864p.bin"); - return s3; -} - -static int s3_bahamas64_available(void) -{ - return rom_present(L"roms/video/s3/bahamas64.bin"); -} - -static int s3_phoenix_vision864_available(void) -{ - return rom_present(L"roms/video/s3/86c864p.bin"); -} - -static void *s3_phoenix_trio32_init(const device_t *info) -{ - s3_t *s3 = s3_init(info, L"roms/video/s3/86c732p.bin", S3_TRIO32); - - s3->id = 0xe1; /*Trio32*/ - s3->id_ext = 0x10; - s3->id_ext_pci = 0x11; - s3->packed_mmio = 1; - - s3->getclock = s3_trio64_getclock; - s3->getclock_p = s3; - - return s3; -} - -static int s3_phoenix_trio32_available(void) -{ - return rom_present(L"roms/video/s3/86c732p.bin"); -} - -static void *s3_trio64_init(const device_t *info, wchar_t *bios_fn) -{ - s3_t *s3 = s3_init(info, bios_fn, S3_TRIO64); - - s3->id = 0xe1; /*Trio64*/ - s3->id_ext = s3->id_ext_pci = 0x11; - s3->packed_mmio = 1; - - s3->getclock = s3_trio64_getclock; - s3->getclock_p = s3; - - return s3; -} - -static void *s3_9fx_init(const device_t *info) -{ - s3_t *s3 = s3_trio64_init(info, L"roms/video/s3/s3_764.bin"); - return s3; -} - -static void *s3_phoenix_trio64_init(const device_t *info) -{ - s3_t *s3 = s3_trio64_init(info, L"roms/video/s3/86c764x1.bin"); - if (device_get_config_int("memory") == 1) - s3->svga.vram_max = 1 << 20; /*Phoenix BIOS does not expect VRAM to be mirrored*/ - return s3; -} - -static void *s3_phoenix_trio64_onboard_init(const device_t *info) -{ - s3_t *s3 = s3_trio64_init(info, NULL); - if (device_get_config_int("memory") == 1) - s3->svga.vram_max = 1 << 20; /*Phoenix BIOS does not expect VRAM to be mirrored*/ - return s3; -} - -static void *s3_diamond_stealth64_init(const device_t *info) -{ - s3_t *s3 = s3_trio64_init(info, L"roms/video/s3/stealt64.bin"); - if (device_get_config_int("memory") == 1) - s3->svga.vram_max = 1 << 20; /*Phoenix BIOS does not expect VRAM to be mirrored*/ - return s3; -} - -static int s3_9fx_available(void) -{ - return rom_present(L"roms/video/s3/s3_764.bin"); -} - -static int s3_phoenix_trio64_available(void) -{ - return rom_present(L"roms/video/s3/86c764x1.bin"); -} - -static int s3_diamond_stealth64_available(void) -{ - return rom_present(L"roms/video/s3/stealt64.bin"); -} - -static void s3_close(void *p) -{ - s3_t *s3 = (s3_t *)p; - - svga_close(&s3->svga); - - thread_kill(s3->fifo_thread); - thread_destroy_event(s3->wake_fifo_thread); - thread_destroy_event(s3->fifo_not_full_event); - - free(s3); -} - -static void s3_speed_changed(void *p) -{ - s3_t *s3 = (s3_t *)p; - - svga_recalctimings(&s3->svga); -} - -static void s3_force_redraw(void *p) -{ - s3_t *s3 = (s3_t *)p; - - s3->svga.fullchange = changeframecount; -} - -static const device_config_t s3_bahamas64_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, - { - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - /*Vision864 also supports 8 MB, however the Paradise BIOS is buggy (VESA modes don't work correctly)*/ - { - "" - } - } - }, - { - "", "", -1 - } -}; - -static const device_config_t s3_9fx_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 2, - { - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ - { - "" - } - } - }, - { - "is_pci", "Bus", CONFIG_SELECTION, "", 1, - { - { - "VLB", 0 - }, - { - "PCI", 1 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -static const device_config_t s3_phoenix_trio32_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 2, - { - { - "512 KB", 0 - }, - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -static const device_config_t s3_phoenix_trio64_onboard_config[] = -{ - { - "memory", "Video memory size", CONFIG_SELECTION, "", 4, - { - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -static const device_config_t s3_phoenix_trio64_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, - { - { - "1 MB", 1 - }, - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - -const device_t s3_bahamas64_vlb_device = -{ - "Paradise Bahamas 64 (S3 Vision864) VLB", - DEVICE_VLB, - 0, - s3_bahamas64_init, - s3_close, - NULL, - s3_bahamas64_available, - s3_speed_changed, - s3_force_redraw, - s3_bahamas64_config -}; - -const device_t s3_bahamas64_pci_device = -{ - "Paradise Bahamas 64 (S3 Vision864) PCI", - DEVICE_PCI, - 0, - s3_bahamas64_init, - s3_close, - NULL, - s3_bahamas64_available, - s3_speed_changed, - s3_force_redraw, - s3_bahamas64_config -}; - -const device_t s3_9fx_vlb_device = -{ - "Number 9 9FX (S3 Trio64) VLB", - DEVICE_VLB, - 0, - s3_9fx_init, - s3_close, - NULL, - s3_9fx_available, - s3_speed_changed, - s3_force_redraw, - s3_9fx_config -}; - -const device_t s3_9fx_pci_device = -{ - "Number 9 9FX (S3 Trio64) PCI", - DEVICE_PCI, - 0, - s3_9fx_init, - s3_close, - NULL, - s3_9fx_available, - s3_speed_changed, - s3_force_redraw, - s3_9fx_config -}; - -const device_t s3_phoenix_trio32_vlb_device = -{ - "Phoenix S3 Trio32 VLB", - DEVICE_VLB, - 0, - s3_phoenix_trio32_init, - s3_close, - NULL, - s3_phoenix_trio32_available, - s3_speed_changed, - s3_force_redraw, - s3_phoenix_trio32_config -}; - -const device_t s3_phoenix_trio32_pci_device = -{ - "Phoenix S3 Trio32 PCI", - DEVICE_PCI, - 0, - s3_phoenix_trio32_init, - s3_close, - NULL, - s3_phoenix_trio32_available, - s3_speed_changed, - s3_force_redraw, - s3_phoenix_trio32_config -}; - -const device_t s3_phoenix_trio64_vlb_device = -{ - "Phoenix S3 Trio64 VLB", - DEVICE_VLB, - 0, - s3_phoenix_trio64_init, - s3_close, - NULL, - s3_phoenix_trio64_available, - s3_speed_changed, - s3_force_redraw, - s3_phoenix_trio64_config -}; - -const device_t s3_phoenix_trio64_onboard_pci_device = -{ - "Phoenix S3 Trio64 On-Board PCI", - DEVICE_PCI, - 1, - s3_phoenix_trio64_onboard_init, - s3_close, - NULL, - NULL, - s3_speed_changed, - s3_force_redraw, - s3_phoenix_trio64_onboard_config -}; - -const device_t s3_phoenix_trio64_pci_device = -{ - "Phoenix S3 Trio64 PCI", - DEVICE_PCI, - 0, - s3_phoenix_trio64_init, - s3_close, - NULL, - s3_phoenix_trio64_available, - s3_speed_changed, - s3_force_redraw, - s3_phoenix_trio64_config -}; - -const device_t s3_phoenix_vision864_vlb_device = -{ - "Phoenix S3 Vision864 VLB", - DEVICE_VLB, - 0, - s3_phoenix_vision864_init, - s3_close, - NULL, - s3_phoenix_vision864_available, - s3_speed_changed, - s3_force_redraw, - s3_bahamas64_config -}; - -const device_t s3_phoenix_vision864_pci_device = -{ - "Phoenix S3 Vision864 PCI", - DEVICE_PCI, - 0, - s3_phoenix_vision864_init, - s3_close, - NULL, - s3_phoenix_vision864_available, - s3_speed_changed, - s3_force_redraw, - s3_bahamas64_config -}; - -const device_t s3_diamond_stealth64_vlb_device = -{ - "S3 Trio64 (Diamond Stealth64 DRAM) VLB", - DEVICE_PCI, - 0, - s3_diamond_stealth64_init, - s3_close, - NULL, - s3_diamond_stealth64_available, - s3_speed_changed, - s3_force_redraw, - s3_phoenix_trio64_config -}; - -const device_t s3_diamond_stealth64_pci_device = -{ - "S3 Trio64 (Diamond Stealth64 DRAM) PCI", - DEVICE_PCI, - 0, - s3_diamond_stealth64_init, - s3_close, - NULL, - s3_diamond_stealth64_available, - s3_speed_changed, - s3_force_redraw, - s3_phoenix_trio64_config -}; diff --git a/backup code/video - Cópia/vid_s3.h b/backup code/video - Cópia/vid_s3.h deleted file mode 100644 index 04888acdb..000000000 --- a/backup code/video - Cópia/vid_s3.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 S3 Trio32, S3 Trio64, and S3 Vision864 - * graphics cards. - * - * Version: @(#)vid_s3.h 1.0.2 2018/03/18 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -const device_t s3_bahamas64_vlb_device; -const device_t s3_bahamas64_pci_device; -const device_t s3_9fx_vlb_device; -const device_t s3_9fx_pci_device; -const device_t s3_phoenix_trio32_vlb_device; -const device_t s3_phoenix_trio32_pci_device; -const device_t s3_phoenix_trio64_vlb_device; -const device_t s3_phoenix_trio64_onboard_pci_device; -const device_t s3_phoenix_trio64_pci_device; -const device_t s3_phoenix_vision864_pci_device; -const device_t s3_phoenix_vision864_vlb_device; -const device_t s3_diamond_stealth64_pci_device; -const device_t s3_diamond_stealth64_vlb_device; -/* const device_t s3_miro_vision964_device; */ diff --git a/backup code/video - Cópia/vid_s3_virge.c b/backup code/video - Cópia/vid_s3_virge.c deleted file mode 100644 index 63e26a2a0..000000000 --- a/backup code/video - Cópia/vid_s3_virge.c +++ /dev/null @@ -1,4328 +0,0 @@ -/* - * 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. - * - * S3 ViRGE emulation. - * - * Version: @(#)vid_s3_virge.c 1.0.11 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "../plat.h" -#include "video.h" -#include "vid_s3_virge.h" -#include "vid_svga.h" -#include "vid_svga_render.h" - - -static uint64_t virge_time = 0; -static int reg_writes = 0, reg_reads = 0; - -static int dither[4][4] = -{ - {0, 4, 1, 5}, - {6, 2, 7, 3}, - {1, 5, 0, 4}, - {7, 3, 6, 2}, -}; - -#define RB_SIZE 256 -#define RB_MASK (RB_SIZE - 1) - -#define RB_ENTRIES (virge->s3d_write_idx - virge->s3d_read_idx) -#define RB_FULL (RB_ENTRIES == RB_SIZE) -#define RB_EMPTY (!RB_ENTRIES) - -#define FIFO_SIZE 65536 -#define FIFO_MASK (FIFO_SIZE - 1) -#define FIFO_ENTRY_SIZE (1 << 31) - -#define FIFO_ENTRIES (virge->fifo_write_idx - virge->fifo_read_idx) -#define FIFO_FULL ((virge->fifo_write_idx - virge->fifo_read_idx) >= FIFO_SIZE) -#define FIFO_EMPTY (virge->fifo_read_idx == virge->fifo_write_idx) - -#define FIFO_TYPE 0xff000000 -#define FIFO_ADDR 0x00ffffff - -enum -{ - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_WORD = (0x02 << 24), - FIFO_WRITE_DWORD = (0x03 << 24) -}; - -typedef struct -{ - uint32_t addr_type; - uint32_t val; -} fifo_entry_t; - -typedef struct s3d_t -{ - uint32_t cmd_set; - int clip_l, clip_r, clip_t, clip_b; - - uint32_t dest_base; - uint32_t dest_str; - - uint32_t z_base; - uint32_t z_str; - - uint32_t tex_base; - uint32_t tex_bdr_clr; - uint32_t tbv, tbu; - int32_t TdVdX, TdUdX; - int32_t TdVdY, TdUdY; - uint32_t tus, tvs; - - int32_t TdZdX, TdZdY; - uint32_t tzs; - - int32_t TdWdX, TdWdY; - uint32_t tws; - - int32_t TdDdX, TdDdY; - uint32_t tds; - - int16_t TdGdX, TdBdX, TdRdX, TdAdX; - int16_t TdGdY, TdBdY, TdRdY, TdAdY; - uint32_t tgs, tbs, trs, tas; - - uint32_t TdXdY12; - uint32_t txend12; - uint32_t TdXdY01; - uint32_t txend01; - uint32_t TdXdY02; - uint32_t txs; - uint32_t tys; - int ty01, ty12, tlr; -} s3d_t; - -typedef struct virge_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t mmio_mapping; - mem_mapping_t new_mmio_mapping; - - rom_t bios_rom; - - svga_t svga; - - uint8_t bank; - uint8_t ma_ext; - - uint8_t virge_id, virge_id_high, virge_id_low, virge_rev; - - uint32_t linear_base, linear_size; - - uint8_t pci_regs[256]; - int card; - - int pci; - int is_375; - - int bilinear_enabled; - int dithering_enabled; - int memory_size; - - int pixel_count, tri_count; - - thread_t *render_thread; - event_t *wake_render_thread; - event_t *wake_main_thread; - event_t *not_full_event; - - uint32_t hwc_fg_col, hwc_bg_col; - int hwc_col_stack_pos; - - struct - { - uint32_t src_base; - uint32_t dest_base; - int clip_l, clip_r, clip_t, clip_b; - int dest_str, src_str; - uint32_t mono_pat_0; - uint32_t mono_pat_1; - uint32_t pat_bg_clr; - uint32_t pat_fg_clr; - uint32_t src_bg_clr; - uint32_t src_fg_clr; - uint32_t cmd_set; - int r_width, r_height; - int rsrc_x, rsrc_y; - int rdest_x, rdest_y; - - int lxend0, lxend1; - int32_t ldx; - uint32_t lxstart, lystart; - int lycnt; - int line_dir; - - int src_x, src_y; - int dest_x, dest_y; - int w, h; - uint8_t rop; - - int data_left_count; - uint32_t data_left; - - uint32_t pattern_8[8*8]; - uint32_t pattern_16[8*8]; - uint32_t pattern_32[8*8]; - - uint32_t prdx; - uint32_t prxstart; - uint32_t pldx; - uint32_t plxstart; - uint32_t pystart; - uint32_t pycnt; - uint32_t dest_l, dest_r; - } s3d; - - s3d_t s3d_tri; - - s3d_t s3d_buffer[RB_SIZE]; - int s3d_read_idx, s3d_write_idx; - int s3d_busy; - - struct - { - uint32_t pri_ctrl; - uint32_t chroma_ctrl; - uint32_t sec_ctrl; - uint32_t chroma_upper_bound; - uint32_t sec_filter; - uint32_t blend_ctrl; - uint32_t pri_fb0, pri_fb1; - uint32_t pri_stride; - uint32_t buffer_ctrl; - uint32_t sec_fb0, sec_fb1; - uint32_t sec_stride; - uint32_t overlay_ctrl; - int32_t k1_vert_scale; - int32_t k2_vert_scale; - int32_t dda_vert_accumulator; - int32_t k1_horiz_scale; - int32_t k2_horiz_scale; - int32_t dda_horiz_accumulator; - uint32_t fifo_ctrl; - uint32_t pri_start; - uint32_t pri_size; - uint32_t sec_start; - uint32_t sec_size; - - int sdif; - - int pri_x, pri_y, pri_w, pri_h; - int sec_x, sec_y, sec_w, sec_h; - } streams; - - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; - - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; - - int virge_busy; - - uint8_t subsys_stat, subsys_cntl; -} virge_t; - -static __inline void wake_fifo_thread(virge_t *virge) -{ - thread_set_event(virge->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ -} - -static void queue_triangle(virge_t *virge); - -static void s3_virge_recalctimings(svga_t *svga); -static void s3_virge_updatemapping(virge_t *virge); - -static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat); - -static uint8_t s3_virge_mmio_read(uint32_t addr, void *p); -static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p); -static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p); -static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p); -static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p); -static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p); - -enum -{ - CMD_SET_AE = 1, - CMD_SET_HC = (1 << 1), - - CMD_SET_FORMAT_MASK = (7 << 2), - CMD_SET_FORMAT_8 = (0 << 2), - CMD_SET_FORMAT_16 = (1 << 2), - CMD_SET_FORMAT_24 = (2 << 2), - - CMD_SET_MS = (1 << 6), - CMD_SET_IDS = (1 << 7), - CMD_SET_MP = (1 << 8), - CMD_SET_TP = (1 << 9), - - CMD_SET_ITA_MASK = (3 << 10), - CMD_SET_ITA_BYTE = (0 << 10), - CMD_SET_ITA_WORD = (1 << 10), - CMD_SET_ITA_DWORD = (2 << 10), - - CMD_SET_ZUP = (1 << 23), - - CMD_SET_ZB_MODE = (3 << 24), - - CMD_SET_XP = (1 << 25), - CMD_SET_YP = (1 << 26), - - CMD_SET_COMMAND_MASK = (15 << 27) -}; - -#define CMD_SET_ABC_SRC (1 << 18) -#define CMD_SET_ABC_ENABLE (1 << 19) -#define CMD_SET_TWE (1 << 26) - -enum -{ - CMD_SET_COMMAND_BITBLT = (0 << 27), - CMD_SET_COMMAND_RECTFILL = (2 << 27), - CMD_SET_COMMAND_LINE = (3 << 27), - CMD_SET_COMMAND_POLY = (5 << 27), - CMD_SET_COMMAND_NOP = (15 << 27) -}; - -#define INT_VSY (1 << 0) -#define INT_S3D_DONE (1 << 1) -#define INT_FIFO_OVF (1 << 2) -#define INT_FIFO_EMP (1 << 3) -#define INT_3DF_EMP (1 << 6) -#define INT_MASK 0xff - - -#ifdef ENABLE_S3_VIRGE_LOG -int s3_virge_do_log = ENABLE_S3_VIRGE_LOG; -#endif - - -static void -s3_virge_log(const char *format, ...) -{ -#ifdef ENABLE_S3_VIRGE_LOG - va_list ap; - - if (s3_virge_do_log) { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} - - -static void s3_virge_update_irqs(virge_t *virge) -{ - if (!virge->pci) - { - return; - } - - if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & virge->subsys_cntl & INT_MASK)) - pci_set_irq(virge->card, PCI_INTA); - else - pci_clear_irq(virge->card, PCI_INTA); -} - -static void s3_virge_out(uint16_t addr, uint8_t val, void *p) -{ - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - uint8_t old; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3c5: - if (svga->seqaddr >= 0x10) - { - svga->seqregs[svga->seqaddr & 0x1f]=val; - svga_recalctimings(svga); - return; - } - if (svga->seqaddr == 4) /*Chain-4 - update banking*/ - { - if (val & 8) svga->write_bank = svga->read_bank = virge->bank << 16; - else svga->write_bank = svga->read_bank = virge->bank << 14; - } - break; - - case 0x3d4: - svga->crtcreg = val; - return; - case 0x3d5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) - return; - if (svga->crtcreg >= 0x80) - return; - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - switch (svga->crtcreg) - { - case 0x31: - virge->ma_ext = (virge->ma_ext & 0x1c) | ((val & 0x30) >> 4); - break; - case 0x32: - s3_virge_update_irqs(virge); - break; - - case 0x69: - virge->ma_ext = val & 0x1f; - break; - - case 0x35: - virge->bank = (virge->bank & 0x70) | (val & 0xf); - if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16; - else svga->write_bank = svga->read_bank = virge->bank << 14; - break; - case 0x51: - virge->bank = (virge->bank & 0x4f) | ((val & 0xc) << 2); - if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16; - else svga->write_bank = svga->read_bank = virge->bank << 14; - virge->ma_ext = (virge->ma_ext & ~0xc) | ((val & 3) << 2); - break; - case 0x6a: - virge->bank = val; - if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16; - else svga->write_bank = svga->read_bank = virge->bank << 14; - break; - - case 0x3a: - if (val & 0x10) svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ - break; - - case 0x45: - svga->hwcursor.ena = val & 1; - break; - case 0x46: case 0x47: case 0x48: case 0x49: - case 0x4c: case 0x4d: case 0x4e: case 0x4f: - svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff; - svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff; - svga->hwcursor.xoff = svga->crtc[0x4e] & 63; - svga->hwcursor.yoff = svga->crtc[0x4f] & 63; - svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); - break; - - case 0x4a: - switch (virge->hwc_col_stack_pos) - { - case 0: - virge->hwc_fg_col = (virge->hwc_fg_col & 0xffff00) | val; - break; - case 1: - virge->hwc_fg_col = (virge->hwc_fg_col & 0xff00ff) | (val << 8); - break; - case 2: - virge->hwc_fg_col = (virge->hwc_fg_col & 0x00ffff) | (val << 16); - break; - } - virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; - break; - case 0x4b: - switch (virge->hwc_col_stack_pos) - { - case 0: - virge->hwc_bg_col = (virge->hwc_bg_col & 0xffff00) | val; - break; - case 1: - virge->hwc_bg_col = (virge->hwc_bg_col & 0xff00ff) | (val << 8); - break; - case 2: - virge->hwc_bg_col = (virge->hwc_bg_col & 0x00ffff) | (val << 16); - break; - } - virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; - break; - - case 0x53: - case 0x58: case 0x59: case 0x5a: - s3_virge_updatemapping(virge); - break; - - case 0x67: - switch (val >> 4) - { - case 2: case 3: svga->bpp = 15; break; - case 4: case 5: svga->bpp = 16; break; - case 7: svga->bpp = 24; break; - case 13: svga->bpp = ((gfxcard == GFX_VIRGEVX_VLB) || (gfxcard == GFX_VIRGEVX_PCI)) ? 24 : 32; break; - default: svga->bpp = 8; break; - } - break; - } - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); -} - -static uint8_t s3_virge_in(uint16_t addr, void *p) -{ - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - uint8_t ret; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3c1: - if (svga->attraddr > 0x14) - ret = 0xff; - else - ret = svga_in(addr, svga); - break; - - case 0x3c5: - if (svga->seqaddr >= 8) - ret = svga->seqregs[svga->seqaddr & 0x1f]; - else if (svga->seqaddr <= 4) - ret = svga_in(addr, svga); - else - ret = 0xff; - break; - - case 0x3D4: - ret = svga->crtcreg; - break; - case 0x3D5: - switch (svga->crtcreg) - { - case 0x2d: ret = virge->virge_id_high; break; /*Extended chip ID*/ - case 0x2e: ret = virge->virge_id_low; break; /*New chip ID*/ - case 0x2f: ret = virge->virge_rev; break; - case 0x30: ret = virge->virge_id; break; /*Chip ID*/ - case 0x31: ret = (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); break; - case 0x35: ret = (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf); break; - case 0x36: ret = (svga->crtc[0x36] & 0xfc) | 2; break; /*PCI bus*/ - case 0x45: virge->hwc_col_stack_pos = 0; ret = svga->crtc[0x45]; break; - case 0x51: ret = (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3); break; - case 0x69: ret = virge->ma_ext; break; - case 0x6a: ret = virge->bank; break; - default: ret = svga->crtc[svga->crtcreg]; break; - } - break; - - default: - ret = svga_in(addr, svga); - break; - } - return ret; -} - -static void s3_virge_recalctimings(svga_t *svga) -{ - virge_t *virge = (virge_t *)svga->p; - - if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; - if (svga->crtc[0x5d] & 0x02) svga->hdisp += 0x100; - if (svga->crtc[0x5e] & 0x01) svga->vtotal += 0x400; - if (svga->crtc[0x5e] & 0x02) svga->dispend += 0x400; - if (svga->crtc[0x5e] & 0x04) svga->vblankstart += 0x400; - if (svga->crtc[0x5e] & 0x10) svga->vsyncstart += 0x400; - if (svga->crtc[0x5e] & 0x40) svga->split += 0x400; - svga->interlace = svga->crtc[0x42] & 0x20; - - if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ - { - svga->ma_latch |= (virge->ma_ext << 16); - if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; - else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; - if (!svga->rowoffset) svga->rowoffset = 256; - - if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) - { - switch (svga->bpp) - { - case 8: - svga->render = svga_render_8bpp_highres; - break; - case 15: - svga->render = svga_render_15bpp_highres; - break; - case 16: - svga->render = svga_render_16bpp_highres; - break; - case 24: - svga->render = svga_render_24bpp_highres; - break; - case 32: - svga->render = svga_render_32bpp_highres; - break; - } - } - - if ((gfxcard != GFX_VIRGEVX_VLB) && (gfxcard != GFX_VIRGEVX_PCI)) - { - if ((svga->bpp == 15) || (svga->bpp == 16)) - { - svga->htotal >>= 1; - svga->hdisp >>= 1; - } - if (svga->bpp == 24) - { - svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ - } - } - svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : ((virge->memory_size << 20) - 1); - } - else /*Streams mode*/ - { - if (virge->streams.buffer_ctrl & 1) - svga->ma_latch = virge->streams.pri_fb1 >> 2; - else - svga->ma_latch = virge->streams.pri_fb0 >> 2; - - svga->hdisp = virge->streams.pri_w + 1; - if (virge->streams.pri_h < svga->dispend) - svga->dispend = virge->streams.pri_h; - - svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x; - svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y; - svga->overlay.ysize = virge->streams.sec_h; - - if (virge->streams.buffer_ctrl & 2) - svga->overlay.addr = virge->streams.sec_fb1; - else - svga->overlay.addr = virge->streams.sec_fb0; - - svga->overlay.ena = (svga->overlay.x >= 0); - svga->overlay.v_acc = virge->streams.dda_vert_accumulator; - svga->rowoffset = virge->streams.pri_stride >> 3; - - switch ((virge->streams.pri_ctrl >> 24) & 0x7) - { - case 0: /*RGB-8 (CLUT)*/ - svga->render = svga_render_8bpp_highres; - break; - case 3: /*KRGB-16 (1.5.5.5)*/ - svga->htotal >>= 1; - svga->render = svga_render_15bpp_highres; - break; - case 5: /*RGB-16 (5.6.5)*/ - svga->htotal >>= 1; - svga->render = svga_render_16bpp_highres; - break; - case 6: /*RGB-24 (8.8.8)*/ - svga->render = svga_render_24bpp_highres; - break; - case 7: /*XRGB-32 (X.8.8.8)*/ - svga->render = svga_render_32bpp_highres; - break; - } - svga->vram_display_mask = (virge->memory_size << 20) - 1; - } - - if (((svga->miscout >> 2) & 3) == 3) - { - int n = svga->seqregs[0x12] & 0x1f; - int r = (svga->seqregs[0x12] >> 5) & ((virge->is_375 || ((gfxcard == GFX_VIRGEVX_VLB) || (gfxcard == GFX_VIRGEVX_PCI))) ? 7 : 3); - int m = svga->seqregs[0x13] & 0x7f; - double freq = (((double)m + 2) / (((double)n + 2) * (double)(1 << r))) * 14318184.0; - - svga->clock = cpuclock / freq; - } -} - -static void s3_virge_updatemapping(virge_t *virge) -{ - svga_t *svga = &virge->svga; - - if (!(virge->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) - { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&virge->linear_mapping); - mem_mapping_disable(&virge->mmio_mapping); - mem_mapping_disable(&virge->new_mmio_mapping); - return; - } - - s3_virge_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); - switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - - virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - - s3_virge_log("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10); - if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/ - { - switch (svga->crtc[0x58] & 3) - { - case 0: /*64k*/ - virge->linear_size = 0x10000; - break; - case 1: /*1mb*/ - virge->linear_size = 0x100000; - break; - case 2: /*2mb*/ - virge->linear_size = 0x200000; - break; - case 3: /*8mb*/ - virge->linear_size = 0x400000; - break; - } - virge->linear_base &= ~(virge->linear_size - 1); - s3_virge_log("Linear framebuffer at %08X size %08X\n", virge->linear_base, virge->linear_size); - if (virge->linear_base == 0xa0000) - { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_disable(&virge->linear_mapping); - } - else - mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); - svga->fb_only = 1; - } - else - { - mem_mapping_disable(&virge->linear_mapping); - svga->fb_only = 0; - } - - s3_virge_log("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18); - if (svga->crtc[0x53] & 0x10) /*Old MMIO*/ - { - if (svga->crtc[0x53] & 0x20) - mem_mapping_set_addr(&virge->mmio_mapping, 0xb8000, 0x8000); - else - mem_mapping_set_addr(&virge->mmio_mapping, 0xa0000, 0x10000); - } - else - mem_mapping_disable(&virge->mmio_mapping); - - if (svga->crtc[0x53] & 0x08) /*New MMIO*/ - mem_mapping_set_addr(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000); - else - mem_mapping_disable(&virge->new_mmio_mapping); - -} - -static void s3_virge_vblank_start(svga_t *svga) -{ - virge_t *virge = (virge_t *)svga->p; - - virge->subsys_stat |= INT_VSY; - s3_virge_update_irqs(virge); -} - -static void s3_virge_wait_fifo_idle(virge_t *virge) -{ - while (!FIFO_EMPTY) - { - wake_fifo_thread(virge); - thread_wait_event(virge->fifo_not_full_event, 1); - } -} - -static uint8_t s3_virge_mmio_read(uint32_t addr, void *p) -{ - virge_t *virge = (virge_t *)p; - uint8_t ret; - - reg_reads++; - switch (addr & 0xffff) - { - case 0x8505: - if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) - ret = 0x10; - else - ret = 0x10 | (1 << 5); - if (!virge->virge_busy) - wake_fifo_thread(virge); - return ret; - - case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: - case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: - case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb: - case 0x83bc: case 0x83bd: case 0x83be: case 0x83bf: - case 0x83c0: case 0x83c1: case 0x83c2: case 0x83c3: - case 0x83c4: case 0x83c5: case 0x83c6: case 0x83c7: - case 0x83c8: case 0x83c9: case 0x83ca: case 0x83cb: - case 0x83cc: case 0x83cd: case 0x83ce: case 0x83cf: - case 0x83d0: case 0x83d1: case 0x83d2: case 0x83d3: - case 0x83d4: case 0x83d5: case 0x83d6: case 0x83d7: - case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: - case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: - return s3_virge_in(addr & 0x3ff, p); - } - return 0xff; -} -static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p) -{ - reg_reads++; - switch (addr & 0xfffe) - { - default: - return s3_virge_mmio_read(addr, p) | (s3_virge_mmio_read(addr + 1, p) << 8); - } - return 0xffff; -} -static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) -{ - virge_t *virge = (virge_t *)p; - uint32_t ret = 0xffffffff; - reg_reads++; - switch (addr & 0xfffc) - { - case 0x8180: - ret = virge->streams.pri_ctrl; - break; - case 0x8184: - ret = virge->streams.chroma_ctrl; - break; - case 0x8190: - ret = virge->streams.sec_ctrl; - break; - case 0x8194: - ret = virge->streams.chroma_upper_bound; - break; - case 0x8198: - ret = virge->streams.sec_filter; - break; - case 0x81a0: - ret = virge->streams.blend_ctrl; - break; - case 0x81c0: - ret = virge->streams.pri_fb0; - break; - case 0x81c4: - ret = virge->streams.pri_fb1; - break; - case 0x81c8: - ret = virge->streams.pri_stride; - break; - case 0x81cc: - ret = virge->streams.buffer_ctrl; - break; - case 0x81d0: - ret = virge->streams.sec_fb0; - break; - case 0x81d4: - ret = virge->streams.sec_fb1; - break; - case 0x81d8: - ret = virge->streams.sec_stride; - break; - case 0x81dc: - ret = virge->streams.overlay_ctrl; - break; - case 0x81e0: - ret = virge->streams.k1_vert_scale; - break; - case 0x81e4: - ret = virge->streams.k2_vert_scale; - break; - case 0x81e8: - ret = virge->streams.dda_vert_accumulator; - break; - case 0x81ec: - ret = virge->streams.fifo_ctrl; - break; - case 0x81f0: - ret = virge->streams.pri_start; - break; - case 0x81f4: - ret = virge->streams.pri_size; - break; - case 0x81f8: - ret = virge->streams.sec_start; - break; - case 0x81fc: - ret = virge->streams.sec_size; - break; - - case 0x8504: - if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) - ret = (0x10 << 8); - else - ret = (0x10 << 8) | (1 << 13); - ret |= virge->subsys_stat; - if (!virge->virge_busy) - wake_fifo_thread(virge); - break; - case 0xa4d4: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.src_base; - break; - case 0xa4d8: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.dest_base; - break; - case 0xa4dc: - s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.clip_l << 16) | virge->s3d.clip_r; - break; - case 0xa4e0: - s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.clip_t << 16) | virge->s3d.clip_b; - break; - case 0xa4e4: - s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.dest_str << 16) | virge->s3d.src_str; - break; - case 0xa4e8: case 0xace8: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.mono_pat_0; - break; - case 0xa4ec: case 0xacec: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.mono_pat_1; - break; - case 0xa4f0: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.pat_bg_clr; - break; - case 0xa4f4: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.pat_fg_clr; - break; - case 0xa4f8: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.src_bg_clr; - break; - case 0xa4fc: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.src_fg_clr; - break; - case 0xa500: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.cmd_set; - break; - case 0xa504: - s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.r_width << 16) | virge->s3d.r_height; - break; - case 0xa508: - s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.rsrc_x << 16) | virge->s3d.rsrc_y; - break; - case 0xa50c: - s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y; - break; - - default: - ret = s3_virge_mmio_read_w(addr, p) | (s3_virge_mmio_read_w(addr + 2, p) << 16); - } - return ret; -} - -static void fifo_thread(void *param) -{ - virge_t *virge = (virge_t *)param; - - while (1) - { - thread_set_event(virge->fifo_not_full_event); - thread_wait_event(virge->wake_fifo_thread, -1); - thread_reset_event(virge->wake_fifo_thread); - virge->virge_busy = 1; - while (!FIFO_EMPTY) - { - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx & FIFO_MASK]; - uint32_t val = fifo->val; - - switch (fifo->addr_type & FIFO_TYPE) - { - case FIFO_WRITE_BYTE: - if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) - s3_virge_bitblt(virge, 8, val); - break; - case FIFO_WRITE_WORD: - if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) - { - if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); - else - s3_virge_bitblt(virge, 16, val); - } - break; - case FIFO_WRITE_DWORD: - if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) - { - if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); - else - s3_virge_bitblt(virge, 32, val); - } - else - { - switch ((fifo->addr_type & FIFO_ADDR) & 0xfffc) - { - case 0xa000: case 0xa004: case 0xa008: case 0xa00c: - case 0xa010: case 0xa014: case 0xa018: case 0xa01c: - case 0xa020: case 0xa024: case 0xa028: case 0xa02c: - case 0xa030: case 0xa034: case 0xa038: case 0xa03c: - case 0xa040: case 0xa044: case 0xa048: case 0xa04c: - case 0xa050: case 0xa054: case 0xa058: case 0xa05c: - case 0xa060: case 0xa064: case 0xa068: case 0xa06c: - case 0xa070: case 0xa074: case 0xa078: case 0xa07c: - case 0xa080: case 0xa084: case 0xa088: case 0xa08c: - case 0xa090: case 0xa094: case 0xa098: case 0xa09c: - case 0xa0a0: case 0xa0a4: case 0xa0a8: case 0xa0ac: - case 0xa0b0: case 0xa0b4: case 0xa0b8: case 0xa0bc: - case 0xa0c0: case 0xa0c4: case 0xa0c8: case 0xa0cc: - case 0xa0d0: case 0xa0d4: case 0xa0d8: case 0xa0dc: - case 0xa0e0: case 0xa0e4: case 0xa0e8: case 0xa0ec: - case 0xa0f0: case 0xa0f4: case 0xa0f8: case 0xa0fc: - case 0xa100: case 0xa104: case 0xa108: case 0xa10c: - case 0xa110: case 0xa114: case 0xa118: case 0xa11c: - case 0xa120: case 0xa124: case 0xa128: case 0xa12c: - case 0xa130: case 0xa134: case 0xa138: case 0xa13c: - case 0xa140: case 0xa144: case 0xa148: case 0xa14c: - case 0xa150: case 0xa154: case 0xa158: case 0xa15c: - case 0xa160: case 0xa164: case 0xa168: case 0xa16c: - case 0xa170: case 0xa174: case 0xa178: case 0xa17c: - case 0xa180: case 0xa184: case 0xa188: case 0xa18c: - case 0xa190: case 0xa194: case 0xa198: case 0xa19c: - case 0xa1a0: case 0xa1a4: case 0xa1a8: case 0xa1ac: - case 0xa1b0: case 0xa1b4: case 0xa1b8: case 0xa1bc: - case 0xa1c0: case 0xa1c4: case 0xa1c8: case 0xa1cc: - case 0xa1d0: case 0xa1d4: case 0xa1d8: case 0xa1dc: - case 0xa1e0: case 0xa1e4: case 0xa1e8: case 0xa1ec: - case 0xa1f0: case 0xa1f4: case 0xa1f8: case 0xa1fc: - { - int x = (fifo->addr_type & FIFO_ADDR) & 4; - int y = ((fifo->addr_type & FIFO_ADDR) >> 3) & 7; - virge->s3d.pattern_8[y*8 + x] = val & 0xff; - virge->s3d.pattern_8[y*8 + x + 1] = val >> 8; - virge->s3d.pattern_8[y*8 + x + 2] = val >> 16; - virge->s3d.pattern_8[y*8 + x + 3] = val >> 24; - - x = ((fifo->addr_type & FIFO_ADDR) >> 1) & 6; - y = ((fifo->addr_type & FIFO_ADDR) >> 4) & 7; - virge->s3d.pattern_16[y*8 + x] = val & 0xffff; - virge->s3d.pattern_16[y*8 + x + 1] = val >> 16; - - x = ((fifo->addr_type & FIFO_ADDR) >> 2) & 7; - y = ((fifo->addr_type & FIFO_ADDR) >> 5) & 7; - virge->s3d.pattern_32[y*8 + x] = val & 0xffffff; - } - break; - - case 0xa4d4: case 0xa8d4: - virge->s3d.src_base = val & 0x3ffff8; - break; - case 0xa4d8: case 0xa8d8: - virge->s3d.dest_base = val & 0x3ffff8; - break; - case 0xa4dc: case 0xa8dc: - virge->s3d.clip_l = (val >> 16) & 0x7ff; - virge->s3d.clip_r = val & 0x7ff; - break; - case 0xa4e0: case 0xa8e0: - virge->s3d.clip_t = (val >> 16) & 0x7ff; - virge->s3d.clip_b = val & 0x7ff; - break; - case 0xa4e4: case 0xa8e4: - virge->s3d.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xa4e8: case 0xace8: - virge->s3d.mono_pat_0 = val; - break; - case 0xa4ec: case 0xacec: - virge->s3d.mono_pat_1 = val; - break; - case 0xa4f0: case 0xacf0: - virge->s3d.pat_bg_clr = val; - break; - case 0xa4f4: case 0xa8f4: case 0xacf4: - virge->s3d.pat_fg_clr = val; - break; - case 0xa4f8: - virge->s3d.src_bg_clr = val; - break; - case 0xa4fc: - virge->s3d.src_fg_clr = val; - break; - case 0xa500: case 0xa900: - virge->s3d.cmd_set = val; - if (!(val & CMD_SET_AE)) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xa504: - virge->s3d.r_width = (val >> 16) & 0x7ff; - virge->s3d.r_height = val & 0x7ff; - break; - case 0xa508: - virge->s3d.rsrc_x = (val >> 16) & 0x7ff; - virge->s3d.rsrc_y = val & 0x7ff; - break; - case 0xa50c: - virge->s3d.rdest_x = (val >> 16) & 0x7ff; - virge->s3d.rdest_y = val & 0x7ff; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xa96c: - virge->s3d.lxend0 = (val >> 16) & 0x7ff; - virge->s3d.lxend1 = val & 0x7ff; - break; - case 0xa970: - virge->s3d.ldx = (int32_t)val; - break; - case 0xa974: - virge->s3d.lxstart = val; - break; - case 0xa978: - virge->s3d.lystart = val & 0x7ff; - break; - case 0xa97c: - virge->s3d.lycnt = val & 0x7ff; - virge->s3d.line_dir = val >> 31; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; - - case 0xad00: - virge->s3d.cmd_set = val; - if (!(val & CMD_SET_AE)) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xad68: - virge->s3d.prdx = val; - break; - case 0xad6c: - virge->s3d.prxstart = val; - break; - case 0xad70: - virge->s3d.pldx = val; - break; - case 0xad74: - virge->s3d.plxstart = val; - break; - case 0xad78: - virge->s3d.pystart = val & 0x7ff; - break; - case 0xad7c: - virge->s3d.pycnt = val & 0x300007ff; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; - - case 0xb4d4: - virge->s3d_tri.z_base = val & 0x3ffff8; - break; - case 0xb4d8: - virge->s3d_tri.dest_base = val & 0x3ffff8; - break; - case 0xb4dc: - virge->s3d_tri.clip_l = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_r = val & 0x7ff; - break; - case 0xb4e0: - virge->s3d_tri.clip_t = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_b = val & 0x7ff; - break; - case 0xb4e4: - virge->s3d_tri.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xb4e8: - virge->s3d_tri.z_str = val & 0xff8; - break; - case 0xb4ec: - virge->s3d_tri.tex_base = val & 0x3ffff8; - break; - case 0xb4f0: - virge->s3d_tri.tex_bdr_clr = val & 0xffffff; - break; - case 0xb500: - virge->s3d_tri.cmd_set = val; - if (!(val & CMD_SET_AE)) - queue_triangle(virge); - break; - case 0xb504: - virge->s3d_tri.tbv = val & 0xfffff; - break; - case 0xb508: - virge->s3d_tri.tbu = val & 0xfffff; - break; - case 0xb50c: - virge->s3d_tri.TdWdX = val; - break; - case 0xb510: - virge->s3d_tri.TdWdY = val; - break; - case 0xb514: - virge->s3d_tri.tws = val; - break; - case 0xb518: - virge->s3d_tri.TdDdX = val; - break; - case 0xb51c: - virge->s3d_tri.TdVdX = val; - break; - case 0xb520: - virge->s3d_tri.TdUdX = val; - break; - case 0xb524: - virge->s3d_tri.TdDdY = val; - break; - case 0xb528: - virge->s3d_tri.TdVdY = val; - break; - case 0xb52c: - virge->s3d_tri.TdUdY = val; - break; - case 0xb530: - virge->s3d_tri.tds = val; - break; - case 0xb534: - virge->s3d_tri.tvs = val; - break; - case 0xb538: - virge->s3d_tri.tus = val; - break; - case 0xb53c: - virge->s3d_tri.TdGdX = val >> 16; - virge->s3d_tri.TdBdX = val & 0xffff; - break; - case 0xb540: - virge->s3d_tri.TdAdX = val >> 16; - virge->s3d_tri.TdRdX = val & 0xffff; - break; - case 0xb544: - virge->s3d_tri.TdGdY = val >> 16; - virge->s3d_tri.TdBdY = val & 0xffff; - break; - case 0xb548: - virge->s3d_tri.TdAdY = val >> 16; - virge->s3d_tri.TdRdY = val & 0xffff; - break; - case 0xb54c: - virge->s3d_tri.tgs = (val >> 16) & 0xffff; - virge->s3d_tri.tbs = val & 0xffff; - break; - case 0xb550: - virge->s3d_tri.tas = (val >> 16) & 0xffff; - virge->s3d_tri.trs = val & 0xffff; - break; - - case 0xb554: - virge->s3d_tri.TdZdX = val; - break; - case 0xb558: - virge->s3d_tri.TdZdY = val; - break; - case 0xb55c: - virge->s3d_tri.tzs = val; - break; - case 0xb560: - virge->s3d_tri.TdXdY12 = val; - break; - case 0xb564: - virge->s3d_tri.txend12 = val; - break; - case 0xb568: - virge->s3d_tri.TdXdY01 = val; - break; - case 0xb56c: - virge->s3d_tri.txend01 = val; - break; - case 0xb570: - virge->s3d_tri.TdXdY02 = val; - break; - case 0xb574: - virge->s3d_tri.txs = val; - break; - case 0xb578: - virge->s3d_tri.tys = val; - break; - case 0xb57c: - virge->s3d_tri.ty01 = (val >> 16) & 0x7ff; - virge->s3d_tri.ty12 = val & 0x7ff; - virge->s3d_tri.tlr = val >> 31; - if (virge->s3d_tri.cmd_set & CMD_SET_AE) - queue_triangle(virge); - break; - } - } - break; - } - - virge->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; - - if (FIFO_ENTRIES > 0xe000) - thread_set_event(virge->fifo_not_full_event); - - end_time = plat_timer_read(); - virge_time += end_time - start_time; - } - virge->virge_busy = 0; - } -} - -static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type) -{ - fifo_entry_t *fifo = &virge->fifo[virge->fifo_write_idx & FIFO_MASK]; - - if (FIFO_FULL) - { - thread_reset_event(virge->fifo_not_full_event); - if (FIFO_FULL) - { - thread_wait_event(virge->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } - - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; - - virge->fifo_write_idx++; - - /* if (FIFO_ENTRIES > 0xe000) - wake_fifo_thread(virge); */ - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(virge); -} - -static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) -{ - virge_t *virge = (virge_t *)p; - - reg_writes++; - if ((addr & 0xfffc) < 0x8000) - { - s3_virge_queue(virge, addr, val, FIFO_WRITE_BYTE); - } - else switch (addr & 0xffff) - { - case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: - case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: - case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb: - case 0x83bc: case 0x83bd: case 0x83be: case 0x83bf: - case 0x83c0: case 0x83c1: case 0x83c2: case 0x83c3: - case 0x83c4: case 0x83c5: case 0x83c6: case 0x83c7: - case 0x83c8: case 0x83c9: case 0x83ca: case 0x83cb: - case 0x83cc: case 0x83cd: case 0x83ce: case 0x83cf: - case 0x83d0: case 0x83d1: case 0x83d2: case 0x83d3: - case 0x83d4: case 0x83d5: case 0x83d6: case 0x83d7: - case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: - case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: - s3_virge_out(addr & 0x3ff, val, p); - break; - } - - -} -static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) -{ - virge_t *virge = (virge_t *)p; - reg_writes++; - if ((addr & 0xfffc) < 0x8000) - { - s3_virge_queue(virge, addr, val, FIFO_WRITE_WORD); - } - else switch (addr & 0xfffe) - { - case 0x83d4: - s3_virge_mmio_write(addr, val, p); - s3_virge_mmio_write(addr + 1, val >> 8, p); - break; - } -} -static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) -{ - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - reg_writes++; - - if ((addr & 0xfffc) < 0x8000) - { - if ((addr & 0xe000) == 0) - { - if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); - else - s3_virge_bitblt(virge, 32, val); - } - else - { - s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD); - } - } - else switch (addr & 0xfffc) - { - case 0: - if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); - else - s3_virge_bitblt(virge, 32, val); - break; - - case 0x8180: - virge->streams.pri_ctrl = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x8184: - virge->streams.chroma_ctrl = val; - break; - case 0x8190: - virge->streams.sec_ctrl = val; - virge->streams.dda_horiz_accumulator = val & 0xfff; - if (val & (1 << 11)) - virge->streams.dda_horiz_accumulator |= 0xfffff800; - virge->streams.sdif = (val >> 24) & 7; - break; - case 0x8194: - virge->streams.chroma_upper_bound = val; - break; - case 0x8198: - virge->streams.sec_filter = val; - virge->streams.k1_horiz_scale = val & 0x7ff; - if (val & (1 << 10)) - virge->streams.k1_horiz_scale |= 0xfffff800; - virge->streams.k2_horiz_scale = (val >> 16) & 0x7ff; - if ((val >> 16) & (1 << 10)) - virge->streams.k2_horiz_scale |= 0xfffff800; - break; - case 0x81a0: - virge->streams.blend_ctrl = val; - break; - case 0x81c0: - virge->streams.pri_fb0 = val & 0x3fffff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81c4: - virge->streams.pri_fb1 = val & 0x3fffff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81c8: - virge->streams.pri_stride = val & 0xfff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81cc: - virge->streams.buffer_ctrl = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81d0: - virge->streams.sec_fb0 = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81d4: - virge->streams.sec_fb1 = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81d8: - virge->streams.sec_stride = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81dc: - virge->streams.overlay_ctrl = val; - break; - case 0x81e0: - virge->streams.k1_vert_scale = val & 0x7ff; - if (val & (1 << 10)) - virge->streams.k1_vert_scale |= 0xfffff800; - break; - case 0x81e4: - virge->streams.k2_vert_scale = val & 0x7ff; - if (val & (1 << 10)) - virge->streams.k2_vert_scale |= 0xfffff800; - break; - case 0x81e8: - virge->streams.dda_vert_accumulator = val & 0xfff; - if (val & (1 << 11)) - virge->streams.dda_vert_accumulator |= 0xfffff800; - break; - case 0x81ec: - virge->streams.fifo_ctrl = val; - break; - case 0x81f0: - virge->streams.pri_start = val; - virge->streams.pri_x = (val >> 16) & 0x7ff; - virge->streams.pri_y = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81f4: - virge->streams.pri_size = val; - virge->streams.pri_w = (val >> 16) & 0x7ff; - virge->streams.pri_h = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81f8: - virge->streams.sec_start = val; - virge->streams.sec_x = (val >> 16) & 0x7ff; - virge->streams.sec_y = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81fc: - virge->streams.sec_size = val; - virge->streams.sec_w = (val >> 16) & 0x7ff; - virge->streams.sec_h = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - - case 0x8504: - virge->subsys_stat &= ~(val & 0xff); - virge->subsys_cntl = (val >> 8); - s3_virge_update_irqs(virge); - break; - - case 0xa000: case 0xa004: case 0xa008: case 0xa00c: - case 0xa010: case 0xa014: case 0xa018: case 0xa01c: - case 0xa020: case 0xa024: case 0xa028: case 0xa02c: - case 0xa030: case 0xa034: case 0xa038: case 0xa03c: - case 0xa040: case 0xa044: case 0xa048: case 0xa04c: - case 0xa050: case 0xa054: case 0xa058: case 0xa05c: - case 0xa060: case 0xa064: case 0xa068: case 0xa06c: - case 0xa070: case 0xa074: case 0xa078: case 0xa07c: - case 0xa080: case 0xa084: case 0xa088: case 0xa08c: - case 0xa090: case 0xa094: case 0xa098: case 0xa09c: - case 0xa0a0: case 0xa0a4: case 0xa0a8: case 0xa0ac: - case 0xa0b0: case 0xa0b4: case 0xa0b8: case 0xa0bc: - case 0xa0c0: case 0xa0c4: case 0xa0c8: case 0xa0cc: - case 0xa0d0: case 0xa0d4: case 0xa0d8: case 0xa0dc: - case 0xa0e0: case 0xa0e4: case 0xa0e8: case 0xa0ec: - case 0xa0f0: case 0xa0f4: case 0xa0f8: case 0xa0fc: - case 0xa100: case 0xa104: case 0xa108: case 0xa10c: - case 0xa110: case 0xa114: case 0xa118: case 0xa11c: - case 0xa120: case 0xa124: case 0xa128: case 0xa12c: - case 0xa130: case 0xa134: case 0xa138: case 0xa13c: - case 0xa140: case 0xa144: case 0xa148: case 0xa14c: - case 0xa150: case 0xa154: case 0xa158: case 0xa15c: - case 0xa160: case 0xa164: case 0xa168: case 0xa16c: - case 0xa170: case 0xa174: case 0xa178: case 0xa17c: - case 0xa180: case 0xa184: case 0xa188: case 0xa18c: - case 0xa190: case 0xa194: case 0xa198: case 0xa19c: - case 0xa1a0: case 0xa1a4: case 0xa1a8: case 0xa1ac: - case 0xa1b0: case 0xa1b4: case 0xa1b8: case 0xa1bc: - case 0xa1c0: case 0xa1c4: case 0xa1c8: case 0xa1cc: - case 0xa1d0: case 0xa1d4: case 0xa1d8: case 0xa1dc: - case 0xa1e0: case 0xa1e4: case 0xa1e8: case 0xa1ec: - case 0xa1f0: case 0xa1f4: case 0xa1f8: case 0xa1fc: - { - int x = addr & 4; - int y = (addr >> 3) & 7; - virge->s3d.pattern_8[y*8 + x] = val & 0xff; - virge->s3d.pattern_8[y*8 + x + 1] = val >> 8; - virge->s3d.pattern_8[y*8 + x + 2] = val >> 16; - virge->s3d.pattern_8[y*8 + x + 3] = val >> 24; - - x = (addr >> 1) & 6; - y = (addr >> 4) & 7; - virge->s3d.pattern_16[y*8 + x] = val & 0xffff; - virge->s3d.pattern_16[y*8 + x + 1] = val >> 16; - - x = (addr >> 2) & 7; - y = (addr >> 5) & 7; - virge->s3d.pattern_32[y*8 + x] = val & 0xffffff; - } - break; - - case 0xa4d4: case 0xa8d4: - virge->s3d.src_base = val & 0x3ffff8; - break; - case 0xa4d8: case 0xa8d8: - virge->s3d.dest_base = val & 0x3ffff8; - break; - case 0xa4dc: case 0xa8dc: - virge->s3d.clip_l = (val >> 16) & 0x7ff; - virge->s3d.clip_r = val & 0x7ff; - break; - case 0xa4e0: case 0xa8e0: - virge->s3d.clip_t = (val >> 16) & 0x7ff; - virge->s3d.clip_b = val & 0x7ff; - break; - case 0xa4e4: case 0xa8e4: - virge->s3d.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xa4e8: case 0xace8: - virge->s3d.mono_pat_0 = val; - break; - case 0xa4ec: case 0xacec: - virge->s3d.mono_pat_1 = val; - break; - case 0xa4f0: case 0xacf0: - virge->s3d.pat_bg_clr = val; - break; - case 0xa4f4: case 0xa8f4: case 0xacf4: - virge->s3d.pat_fg_clr = val; - break; - case 0xa4f8: - virge->s3d.src_bg_clr = val; - break; - case 0xa4fc: - virge->s3d.src_fg_clr = val; - break; - case 0xa500: case 0xa900: - virge->s3d.cmd_set = val; - if (!(val & CMD_SET_AE)) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xa504: - virge->s3d.r_width = (val >> 16) & 0x7ff; - virge->s3d.r_height = val & 0x7ff; - break; - case 0xa508: - virge->s3d.rsrc_x = (val >> 16) & 0x7ff; - virge->s3d.rsrc_y = val & 0x7ff; - break; - case 0xa50c: - virge->s3d.rdest_x = (val >> 16) & 0x7ff; - virge->s3d.rdest_y = val & 0x7ff; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xa96c: - virge->s3d.lxend0 = (val >> 16) & 0x7ff; - virge->s3d.lxend1 = val & 0x7ff; - break; - case 0xa970: - virge->s3d.ldx = (int32_t)val; - break; - case 0xa974: - virge->s3d.lxstart = val; - break; - case 0xa978: - virge->s3d.lystart = val & 0x7ff; - break; - case 0xa97c: - virge->s3d.lycnt = val & 0x7ff; - virge->s3d.line_dir = val >> 31; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; - - case 0xad00: - virge->s3d.cmd_set = val; - if (!(val & CMD_SET_AE)) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xad68: - virge->s3d.prdx = val; - break; - case 0xad6c: - virge->s3d.prxstart = val; - break; - case 0xad70: - virge->s3d.pldx = val; - break; - case 0xad74: - virge->s3d.plxstart = val; - break; - case 0xad78: - virge->s3d.pystart = val & 0x7ff; - break; - case 0xad7c: - virge->s3d.pycnt = val & 0x300007ff; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; - - case 0xb4d4: - virge->s3d_tri.z_base = val & 0x3ffff8; - break; - case 0xb4d8: - virge->s3d_tri.dest_base = val & 0x3ffff8; - break; - case 0xb4dc: - virge->s3d_tri.clip_l = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_r = val & 0x7ff; - break; - case 0xb4e0: - virge->s3d_tri.clip_t = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_b = val & 0x7ff; - break; - case 0xb4e4: - virge->s3d_tri.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xb4e8: - virge->s3d_tri.z_str = val & 0xff8; - break; - case 0xb4ec: - virge->s3d_tri.tex_base = val & 0x3ffff8; - break; - case 0xb4f0: - virge->s3d_tri.tex_bdr_clr = val & 0xffffff; - break; - case 0xb500: - virge->s3d_tri.cmd_set = val; - if (!(val & CMD_SET_AE)) - queue_triangle(virge); - break; - case 0xb504: - virge->s3d_tri.tbv = val & 0xfffff; - break; - case 0xb508: - virge->s3d_tri.tbu = val & 0xfffff; - break; - case 0xb50c: - virge->s3d_tri.TdWdX = val; - break; - case 0xb510: - virge->s3d_tri.TdWdY = val; - break; - case 0xb514: - virge->s3d_tri.tws = val; - break; - case 0xb518: - virge->s3d_tri.TdDdX = val; - break; - case 0xb51c: - virge->s3d_tri.TdVdX = val; - break; - case 0xb520: - virge->s3d_tri.TdUdX = val; - break; - case 0xb524: - virge->s3d_tri.TdDdY = val; - break; - case 0xb528: - virge->s3d_tri.TdVdY = val; - break; - case 0xb52c: - virge->s3d_tri.TdUdY = val; - break; - case 0xb530: - virge->s3d_tri.tds = val; - break; - case 0xb534: - virge->s3d_tri.tvs = val; - break; - case 0xb538: - virge->s3d_tri.tus = val; - break; - case 0xb53c: - virge->s3d_tri.TdGdX = val >> 16; - virge->s3d_tri.TdBdX = val & 0xffff; - break; - case 0xb540: - virge->s3d_tri.TdAdX = val >> 16; - virge->s3d_tri.TdRdX = val & 0xffff; - break; - case 0xb544: - virge->s3d_tri.TdGdY = val >> 16; - virge->s3d_tri.TdBdY = val & 0xffff; - break; - case 0xb548: - virge->s3d_tri.TdAdY = val >> 16; - virge->s3d_tri.TdRdY = val & 0xffff; - break; - case 0xb54c: - virge->s3d_tri.tgs = (val >> 16) & 0xffff; - virge->s3d_tri.tbs = val & 0xffff; - break; - case 0xb550: - virge->s3d_tri.tas = (val >> 16) & 0xffff; - virge->s3d_tri.trs = val & 0xffff; - break; - - case 0xb554: - virge->s3d_tri.TdZdX = val; - break; - case 0xb558: - virge->s3d_tri.TdZdY = val; - break; - case 0xb55c: - virge->s3d_tri.tzs = val; - break; - case 0xb560: - virge->s3d_tri.TdXdY12 = val; - break; - case 0xb564: - virge->s3d_tri.txend12 = val; - break; - case 0xb568: - virge->s3d_tri.TdXdY01 = val; - break; - case 0xb56c: - virge->s3d_tri.txend01 = val; - break; - case 0xb570: - virge->s3d_tri.TdXdY02 = val; - break; - case 0xb574: - virge->s3d_tri.txs = val; - break; - case 0xb578: - virge->s3d_tri.tys = val; - break; - case 0xb57c: - virge->s3d_tri.ty01 = (val >> 16) & 0x7ff; - virge->s3d_tri.ty12 = val & 0x7ff; - virge->s3d_tri.tlr = val >> 31; - if (virge->s3d_tri.cmd_set & CMD_SET_AE) - queue_triangle(virge); - break; - } -} - -#define READ(addr, val) \ - do \ - { \ - switch (bpp) \ - { \ - case 0: /*8 bpp*/ \ - val = vram[addr & svga->vram_mask]; \ - break; \ - case 1: /*16 bpp*/ \ - val = *(uint16_t *)&vram[addr & svga->vram_mask]; \ - break; \ - case 2: /*24 bpp*/ \ - val = (*(uint32_t *)&vram[addr & svga->vram_mask]) & 0xffffff; \ - break; \ - } \ - } while (0) - -#define Z_READ(addr) *(uint16_t *)&vram[addr & svga->vram_mask] - -#define Z_WRITE(addr, val) if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) *(uint16_t *)&vram[addr & svga->vram_mask] = val - -#define CLIP(x, y) \ - do \ - { \ - if ((virge->s3d.cmd_set & CMD_SET_HC) && \ - (x < virge->s3d.clip_l || \ - x > virge->s3d.clip_r || \ - y < virge->s3d.clip_t || \ - y > virge->s3d.clip_b)) \ - update = 0; \ - } while (0) - -#define CLIP_3D(x, y) \ - do \ - { \ - if ((s3d_tri->cmd_set & CMD_SET_HC) && \ - (x < s3d_tri->clip_l || \ - x > s3d_tri->clip_r || \ - y < s3d_tri->clip_t || \ - y > s3d_tri->clip_b)) \ - update = 0; \ - } while (0) - -#define Z_CLIP(Zzb, Zs) \ - do \ - { \ - if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) \ - switch ((s3d_tri->cmd_set >> 20) & 7) \ - { \ - case 0: update = 0; break; \ - case 1: if (Zs <= Zzb) update = 0; else Zzb = Zs; break; \ - case 2: if (Zs != Zzb) update = 0; else Zzb = Zs; break; \ - case 3: if (Zs < Zzb) update = 0; else Zzb = Zs; break; \ - case 4: if (Zs >= Zzb) update = 0; else Zzb = Zs; break; \ - case 5: if (Zs == Zzb) update = 0; else Zzb = Zs; break; \ - case 6: if (Zs > Zzb) update = 0; else Zzb = Zs; break; \ - case 7: update = 1; Zzb = Zs; break; \ - } \ - } while (0) - -#define MIX() \ - do \ - { \ - int c; \ - for (c = 0; c < 24; c++) \ - { \ - int d = (dest & (1 << c)) ? 1 : 0; \ - if (source & (1 << c)) d |= 2; \ - if (pattern & (1 << c)) d |= 4; \ - if (virge->s3d.rop & (1 << d)) out |= (1 << c); \ - } \ - } while (0) - -#define WRITE(addr, val) \ - do \ - { \ - switch (bpp) \ - { \ - case 0: /*8 bpp*/ \ - vram[addr & svga->vram_mask] = val; \ - virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ - break; \ - case 1: /*16 bpp*/ \ - *(uint16_t *)&vram[addr & svga->vram_mask] = val; \ - virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ - break; \ - case 2: /*24 bpp*/ \ - *(uint32_t *)&vram[addr & svga->vram_mask] = (val & 0xffffff) | \ - (vram[(addr + 3) & svga->vram_mask] << 24); \ - virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ - break; \ - } \ - } while (0) - -static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) -{ - svga_t *svga = &virge->svga; - uint8_t *vram = virge->svga.vram; - uint32_t mono_pattern[64]; - int count_mask; - int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1; - int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1; - int bpp; - int x_mul; - int cpu_dat_shift; - uint32_t *pattern_data; - uint32_t src_fg_clr, src_bg_clr; - uint32_t src_addr; - uint32_t dest_addr; - uint32_t source = 0, dest = 0, pattern; - uint32_t out = 0; - int update; - - switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) - { - case CMD_SET_FORMAT_8: - bpp = 0; - x_mul = 1; - cpu_dat_shift = 8; - pattern_data = virge->s3d.pattern_8; - src_fg_clr = virge->s3d.src_fg_clr & 0xff; - src_bg_clr = virge->s3d.src_bg_clr & 0xff; - break; - case CMD_SET_FORMAT_16: - bpp = 1; - x_mul = 2; - cpu_dat_shift = 16; - pattern_data = virge->s3d.pattern_16; - src_fg_clr = virge->s3d.src_fg_clr & 0xffff; - src_bg_clr = virge->s3d.src_bg_clr & 0xffff; - break; - case CMD_SET_FORMAT_24: - default: - bpp = 2; - x_mul = 3; - cpu_dat_shift = 24; - pattern_data = virge->s3d.pattern_32; - src_fg_clr = virge->s3d.src_fg_clr; - src_bg_clr = virge->s3d.src_bg_clr; - break; - } - if (virge->s3d.cmd_set & CMD_SET_MP) - pattern_data = mono_pattern; - - switch (virge->s3d.cmd_set & CMD_SET_ITA_MASK) - { - case CMD_SET_ITA_BYTE: - count_mask = ~0x7; - break; - case CMD_SET_ITA_WORD: - count_mask = ~0xf; - break; - case CMD_SET_ITA_DWORD: - default: - count_mask = ~0x1f; - break; - } - if (virge->s3d.cmd_set & CMD_SET_MP) - { - int x, y; - for (y = 0; y < 4; y++) - { - for (x = 0; x < 8; x++) - { - if (virge->s3d.mono_pat_0 & (1 << (x + y*8))) - mono_pattern[y*8 + x] = virge->s3d.pat_fg_clr; - else - mono_pattern[y*8 + x] = virge->s3d.pat_bg_clr; - if (virge->s3d.mono_pat_1 & (1 << (x + y*8))) - mono_pattern[(y+4)*8 + x] = virge->s3d.pat_fg_clr; - else - mono_pattern[(y+4)*8 + x] = virge->s3d.pat_bg_clr; - } - } - } - switch (virge->s3d.cmd_set & CMD_SET_COMMAND_MASK) - { - case CMD_SET_COMMAND_NOP: - break; - - case CMD_SET_COMMAND_BITBLT: - if (count == -1) - { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.src_y = virge->s3d.rsrc_y; - virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.dest_y = virge->s3d.rdest_y; - virge->s3d.w = virge->s3d.r_width; - virge->s3d.h = virge->s3d.r_height; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - virge->s3d.data_left_count = 0; - - s3_virge_log("BitBlt start %i,%i %i,%i %i,%i %02X %x %x\n", - virge->s3d.src_x, - virge->s3d.src_y, - virge->s3d.dest_x, - virge->s3d.dest_y, - virge->s3d.w, - virge->s3d.h, - virge->s3d.rop, - virge->s3d.src_base, - virge->s3d.dest_base); - - if (virge->s3d.cmd_set & CMD_SET_IDS) - return; - } - if (!virge->s3d.h) - return; - while (count) - { - src_addr = virge->s3d.src_base + (virge->s3d.src_x * x_mul) + (virge->s3d.src_y * virge->s3d.src_str); - dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); - out = 0; - update = 1; - - switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) - { - case 0: - case CMD_SET_MS: - READ(src_addr, source); - if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) - update = 0; - break; - case CMD_SET_IDS: - if (virge->s3d.data_left_count) - { - /*Handle shifting for 24-bit data*/ - source = virge->s3d.data_left; - source |= ((cpu_dat << virge->s3d.data_left_count) & ~0xff000000); - cpu_dat >>= (cpu_dat_shift - virge->s3d.data_left_count); - count -= (cpu_dat_shift - virge->s3d.data_left_count); - virge->s3d.data_left_count = 0; - if (count < cpu_dat_shift) - { - virge->s3d.data_left = cpu_dat; - virge->s3d.data_left_count = count; - count = 0; - } - } - else - { - source = cpu_dat; - cpu_dat >>= cpu_dat_shift; - count -= cpu_dat_shift; - if (count < cpu_dat_shift) - { - virge->s3d.data_left = cpu_dat; - virge->s3d.data_left_count = count; - count = 0; - } - } - if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) - update = 0; - break; - case CMD_SET_IDS | CMD_SET_MS: - source = (cpu_dat & (1 << 31)) ? src_fg_clr : src_bg_clr; - if ((virge->s3d.cmd_set & CMD_SET_TP) && !(cpu_dat & (1 << 31))) - update = 0; - cpu_dat <<= 1; - count--; - break; - } - - CLIP(virge->s3d.dest_x, virge->s3d.dest_y); - - if (update) - { - READ(dest_addr, dest); - pattern = pattern_data[(virge->s3d.dest_y & 7)*8 + (virge->s3d.dest_x & 7)]; - MIX(); - - WRITE(dest_addr, out); - } - - virge->s3d.src_x += x_inc; - virge->s3d.src_x &= 0x7ff; - virge->s3d.dest_x += x_inc; - virge->s3d.dest_x &= 0x7ff; - if (!virge->s3d.w) - { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.w = virge->s3d.r_width; - - virge->s3d.src_y += y_inc; - virge->s3d.dest_y += y_inc; - virge->s3d.h--; - - switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) - { - case CMD_SET_IDS: - cpu_dat >>= (count - (count & count_mask)); - count &= count_mask; - virge->s3d.data_left_count = 0; - break; - - case CMD_SET_IDS | CMD_SET_MS: - cpu_dat <<= (count - (count & count_mask)); - count &= count_mask; - break; - } - if (!virge->s3d.h) - { - return; - } - } - else - virge->s3d.w--; - } - break; - - case CMD_SET_COMMAND_RECTFILL: - /*No source, pattern = pat_fg_clr*/ - if (count == -1) - { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.src_y = virge->s3d.rsrc_y; - virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.dest_y = virge->s3d.rdest_y; - virge->s3d.w = virge->s3d.r_width; - virge->s3d.h = virge->s3d.r_height; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - - s3_virge_log("RctFll start %i,%i %i,%i %02X %08x\n", virge->s3d.dest_x, - virge->s3d.dest_y, - virge->s3d.w, - virge->s3d.h, - virge->s3d.rop, virge->s3d.dest_base); - } - - while (count && virge->s3d.h) - { - uint32_t dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); - uint32_t source = 0, dest = 0, pattern = virge->s3d.pat_fg_clr; - uint32_t out = 0; - int update = 1; - - CLIP(virge->s3d.dest_x, virge->s3d.dest_y); - - if (update) - { - READ(dest_addr, dest); - - MIX(); - - WRITE(dest_addr, out); - } - - virge->s3d.src_x += x_inc; - virge->s3d.src_x &= 0x7ff; - virge->s3d.dest_x += x_inc; - virge->s3d.dest_x &= 0x7ff; - if (!virge->s3d.w) - { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.w = virge->s3d.r_width; - - virge->s3d.src_y += y_inc; - virge->s3d.dest_y += y_inc; - virge->s3d.h--; - if (!virge->s3d.h) - { - return; - } - } - else - virge->s3d.w--; - count--; - } - break; - - case CMD_SET_COMMAND_LINE: - if (count == -1) - { - virge->s3d.dest_x = virge->s3d.lxstart; - virge->s3d.dest_y = virge->s3d.lystart; - virge->s3d.h = virge->s3d.lycnt; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - } - while (virge->s3d.h) - { - int x; - int new_x; - int first_pixel = 1; - - x = virge->s3d.dest_x >> 20; - - if (virge->s3d.h == virge->s3d.lycnt && - ((virge->s3d.line_dir && x > virge->s3d.lxend0) || - (!virge->s3d.line_dir && x < virge->s3d.lxend0))) - x = virge->s3d.lxend0; - - if (virge->s3d.h == 1) - new_x = virge->s3d.lxend1 + (virge->s3d.line_dir ? 1 : -1); - else - new_x = (virge->s3d.dest_x + virge->s3d.ldx) >> 20; - - - if ((virge->s3d.line_dir && x > new_x) || - (!virge->s3d.line_dir && x < new_x)) - goto skip_line; - - do - { - uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); - uint32_t source = 0, dest = 0, pattern; - uint32_t out = 0; - int update = 1; - - if ((virge->s3d.h == virge->s3d.lycnt || !first_pixel) && - ((virge->s3d.line_dir && x < virge->s3d.lxend0) || - (!virge->s3d.line_dir && x > virge->s3d.lxend0))) - update = 0; - - if ((virge->s3d.h == 1 || !first_pixel) && - ((virge->s3d.line_dir && x > virge->s3d.lxend1) || - (!virge->s3d.line_dir && x < virge->s3d.lxend1))) - update = 0; - - CLIP(x, virge->s3d.dest_y); - - if (update) - { - READ(dest_addr, dest); - pattern = virge->s3d.pat_fg_clr; - - MIX(); - - WRITE(dest_addr, out); - } - - if (x < new_x) - x++; - else if (x > new_x) - x--; - first_pixel = 0; - } while (x != new_x); - -skip_line: - virge->s3d.dest_x += virge->s3d.ldx; - virge->s3d.dest_y--; - virge->s3d.h--; - } - break; - - case CMD_SET_COMMAND_POLY: - /*No source*/ - if (virge->s3d.pycnt & (1 << 28)) - virge->s3d.dest_r = virge->s3d.prxstart; - if (virge->s3d.pycnt & (1 << 29)) - virge->s3d.dest_l = virge->s3d.plxstart; - virge->s3d.h = virge->s3d.pycnt & 0x7ff; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - while (virge->s3d.h) - { - int x = virge->s3d.dest_l >> 20; - int xend = virge->s3d.dest_r >> 20; - int y = virge->s3d.pystart & 0x7ff; - int xdir = (x < xend) ? 1 : -1; - do - { - uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (y * virge->s3d.dest_str); - uint32_t source = 0, dest = 0, pattern; - uint32_t out = 0; - int update = 1; - - CLIP(x, y); - - if (update) - { - READ(dest_addr, dest); - pattern = pattern_data[(y & 7)*8 + (x & 7)]; - MIX(); - - WRITE(dest_addr, out); - } - - x = (x + xdir) & 0x7ff; - } - while (x != (xend + xdir)); - - virge->s3d.dest_l += virge->s3d.pldx; - virge->s3d.dest_r += virge->s3d.prdx; - virge->s3d.h--; - virge->s3d.pystart = (virge->s3d.pystart - 1) & 0x7ff; - } - break; - - default: - fatal("s3_virge_bitblt : blit command %i %08x\n", (virge->s3d.cmd_set >> 27) & 0xf, virge->s3d.cmd_set); - } -} - -#define RGB15_TO_24(val, r, g, b) b = ((val & 0x001f) << 3) | ((val & 0x001f) >> 2); \ - g = ((val & 0x03e0) >> 2) | ((val & 0x03e0) >> 7); \ - r = ((val & 0x7c00) >> 7) | ((val & 0x7c00) >> 12); - -#define RGB24_TO_24(val, r, g, b) b = val & 0xff; \ - g = (val & 0xff00) >> 8; \ - r = (val & 0xff0000) >> 16 - -#define RGB15(r, g, b, dest) \ - if (virge->dithering_enabled) \ - { \ - int add = dither[_y & 3][_x & 3]; \ - int _r = (r > 248) ? 248 : r+add; \ - int _g = (g > 248) ? 248 : g+add; \ - int _b = (b > 248) ? 248 : b+add; \ - dest = ((_b >> 3) & 0x1f) | (((_g >> 3) & 0x1f) << 5) | (((_r >> 3) & 0x1f) << 10); \ - } \ - else \ - dest = ((b >> 3) & 0x1f) | (((g >> 3) & 0x1f) << 5) | (((r >> 3) & 0x1f) << 10) - -#define RGB24(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) - -typedef struct rgba_t -{ - int r, g, b, a; -} rgba_t; - -typedef struct s3d_state_t -{ - int32_t r, g, b, a, u, v, d, w; - - int32_t base_r, base_g, base_b, base_a, base_u, base_v, base_d, base_w; - - uint32_t base_z; - - uint32_t tbu, tbv; - - uint32_t cmd_set; - int max_d; - - uint16_t *texture[10]; - - uint32_t tex_bdr_clr; - - int32_t x1, x2; - int y; - - rgba_t dest_rgba; -} s3d_state_t; - -typedef struct s3d_texture_state_t -{ - int level; - int texture_shift; - - int32_t u, v; -} s3d_texture_state_t; - -static void (*tex_read)(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out); -static void (*tex_sample)(s3d_state_t *state); -static void (*dest_pixel)(s3d_state_t *state); - -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -static int _x, _y; - -static void tex_ARGB1555(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) -{ - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; - - out->r = ((val & 0x7c00) >> 7) | ((val & 0x7000) >> 12); - out->g = ((val & 0x03e0) >> 2) | ((val & 0x0380) >> 7); - out->b = ((val & 0x001f) << 3) | ((val & 0x001c) >> 2); - out->a = (val & 0x8000) ? 0xff : 0; -} - -static void tex_ARGB1555_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) -{ - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; - - if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) - val = state->tex_bdr_clr; - - out->r = ((val & 0x7c00) >> 7) | ((val & 0x7000) >> 12); - out->g = ((val & 0x03e0) >> 2) | ((val & 0x0380) >> 7); - out->b = ((val & 0x001f) << 3) | ((val & 0x001c) >> 2); - out->a = (val & 0x8000) ? 0xff : 0; -} - -static void tex_ARGB4444(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) -{ - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; - - out->r = ((val & 0x0f00) >> 4) | ((val & 0x0f00) >> 8); - out->g = (val & 0x00f0) | ((val & 0x00f0) >> 4); - out->b = ((val & 0x000f) << 4) | (val & 0x000f); - out->a = ((val & 0xf000) >> 8) | ((val & 0xf000) >> 12); -} - -static void tex_ARGB4444_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) -{ - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; - - if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) - val = state->tex_bdr_clr; - - out->r = ((val & 0x0f00) >> 4) | ((val & 0x0f00) >> 8); - out->g = (val & 0x00f0) | ((val & 0x00f0) >> 4); - out->b = ((val & 0x000f) << 4) | (val & 0x000f); - out->a = ((val & 0xf000) >> 8) | ((val & 0xf000) >> 12); -} - -static void tex_ARGB8888(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) -{ - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint32_t val = ((uint32_t *)state->texture[texture_state->level])[offset]; - - out->r = (val >> 16) & 0xff; - out->g = (val >> 8) & 0xff; - out->b = val & 0xff; - out->a = (val >> 24) & 0xff; -} -static void tex_ARGB8888_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) -{ - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint32_t val = ((uint32_t *)state->texture[texture_state->level])[offset]; - - if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) - val = state->tex_bdr_clr; - - out->r = (val >> 16) & 0xff; - out->g = (val >> 8) & 0xff; - out->b = val & 0xff; - out->a = (val >> 24) & 0xff; -} - -static void tex_sample_normal(s3d_state_t *state) -{ - s3d_texture_state_t texture_state; - - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; - - tex_read(state, &texture_state, &state->dest_rgba); -} - -static void tex_sample_normal_filter(s3d_state_t *state) -{ - s3d_texture_state_t texture_state; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; - - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; - - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &tex_samples[0]); - du = (texture_state.u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (texture_state.v >> (texture_state.texture_shift - 8)) & 0xff; - - texture_state.u = state->u + state->tbu + tex_offset; - texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &tex_samples[1]); - - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); - - texture_state.u = state->u + state->tbu + tex_offset; - texture_state.v = state->v + state->tbv + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); - - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; - - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; -} - -static void tex_sample_mipmap(s3d_state_t *state) -{ - s3d_texture_state_t texture_state; - - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; - - tex_read(state, &texture_state, &state->dest_rgba); -} - -static void tex_sample_mipmap_filter(s3d_state_t *state) -{ - s3d_texture_state_t texture_state; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; - - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; - - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &tex_samples[0]); - du = (texture_state.u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (texture_state.v >> (texture_state.texture_shift - 8)) & 0xff; - - texture_state.u = state->u + state->tbu + tex_offset; - texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &tex_samples[1]); - - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); - - texture_state.u = state->u + state->tbu + tex_offset; - texture_state.v = state->v + state->tbv + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); - - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; - - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; -} - -static void tex_sample_persp_normal(s3d_state_t *state) -{ - s3d_texture_state_t texture_state; - int32_t w = 0; - - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; - texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; - - tex_read(state, &texture_state, &state->dest_rgba); -} - -static void tex_sample_persp_normal_filter(s3d_state_t *state) -{ - s3d_texture_state_t texture_state; - int32_t w = 0, u, v; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; - - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - - u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; - v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; - - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; - - texture_state.u = u; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[0]); - du = (u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (v >> (texture_state.texture_shift - 8)) & 0xff; - - texture_state.u = u + tex_offset; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[1]); - - texture_state.u = u; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); - - texture_state.u = u + tex_offset; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); - - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; - - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; -} - -static void tex_sample_persp_normal_375(s3d_state_t *state) -{ - s3d_texture_state_t texture_state; - int32_t w = 0; - - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; - texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - - tex_read(state, &texture_state, &state->dest_rgba); -} - -static void tex_sample_persp_normal_filter_375(s3d_state_t *state) -{ - s3d_texture_state_t texture_state; - int32_t w = 0, u, v; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; - - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - - u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; - v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; - - texture_state.u = u; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[0]); - du = (u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (v >> (texture_state.texture_shift - 8)) & 0xff; - - texture_state.u = u + tex_offset; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[1]); - - texture_state.u = u; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); - - texture_state.u = u + tex_offset; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); - - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; - - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; -} - - -static void tex_sample_persp_mipmap(s3d_state_t *state) -{ - s3d_texture_state_t texture_state; - int32_t w = 0; - - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; - texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; - - tex_read(state, &texture_state, &state->dest_rgba); -} - -static void tex_sample_persp_mipmap_filter(s3d_state_t *state) -{ - s3d_texture_state_t texture_state; - int32_t w = 0, u, v; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; - - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - - u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; - v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; - - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; - - texture_state.u = u; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[0]); - du = (u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (v >> (texture_state.texture_shift - 8)) & 0xff; - - texture_state.u = u + tex_offset; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[1]); - - texture_state.u = u; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); - - texture_state.u = u + tex_offset; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); - - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; - - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; -} - -static void tex_sample_persp_mipmap_375(s3d_state_t *state) -{ - s3d_texture_state_t texture_state; - int32_t w = 0; - - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; - texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - - tex_read(state, &texture_state, &state->dest_rgba); -} - -static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state) -{ - s3d_texture_state_t texture_state; - int32_t w = 0, u, v; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; - - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - - u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; - v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; - - texture_state.u = u; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[0]); - du = (u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (v >> (texture_state.texture_shift - 8)) & 0xff; - - texture_state.u = u + tex_offset; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[1]); - - texture_state.u = u; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); - - texture_state.u = u + tex_offset; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); - - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; - - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; -} - - -#define CLAMP(x) do \ - { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } \ - while (0) - -#define CLAMP_RGBA(r, g, b, a) \ - if ((r) & ~0xff) \ - r = ((r) < 0) ? 0 : 0xff; \ - if ((g) & ~0xff) \ - g = ((g) < 0) ? 0 : 0xff; \ - if ((b) & ~0xff) \ - b = ((b) < 0) ? 0 : 0xff; \ - if ((a) & ~0xff) \ - a = ((a) < 0) ? 0 : 0xff; - -#define CLAMP_RGB(r, g, b) do \ - { \ - if ((r) < 0) \ - r = 0; \ - if ((r) > 0xff) \ - r = 0xff; \ - if ((g) < 0) \ - g = 0; \ - if ((g) > 0xff) \ - g = 0xff; \ - if ((b) < 0) \ - b = 0; \ - if ((b) > 0xff) \ - b = 0xff; \ - } \ - while (0) - -static void dest_pixel_gouraud_shaded_triangle(s3d_state_t *state) -{ - state->dest_rgba.r = state->r >> 7; - CLAMP(state->dest_rgba.r); - - state->dest_rgba.g = state->g >> 7; - CLAMP(state->dest_rgba.g); - - state->dest_rgba.b = state->b >> 7; - CLAMP(state->dest_rgba.b); - - state->dest_rgba.a = state->a >> 7; - CLAMP(state->dest_rgba.a); -} - -static void dest_pixel_unlit_texture_triangle(s3d_state_t *state) -{ - tex_sample(state); - - if (state->cmd_set & CMD_SET_ABC_SRC) - state->dest_rgba.a = state->a >> 7; -} - -static void dest_pixel_lit_texture_decal(s3d_state_t *state) -{ - tex_sample(state); - - if (state->cmd_set & CMD_SET_ABC_SRC) - state->dest_rgba.a = state->a >> 7; -} - -static void dest_pixel_lit_texture_reflection(s3d_state_t *state) -{ - tex_sample(state); - - state->dest_rgba.r += (state->r >> 7); - state->dest_rgba.g += (state->g >> 7); - state->dest_rgba.b += (state->b >> 7); - if (state->cmd_set & CMD_SET_ABC_SRC) - state->dest_rgba.a += (state->a >> 7); - - CLAMP_RGBA(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, state->dest_rgba.a); -} - -static void dest_pixel_lit_texture_modulate(s3d_state_t *state) -{ - int r = state->r >> 7, g = state->g >> 7, b = state->b >> 7, a = state->a >> 7; - - tex_sample(state); - - CLAMP_RGBA(r, g, b, a); - - state->dest_rgba.r = ((state->dest_rgba.r) * r) >> 8; - state->dest_rgba.g = ((state->dest_rgba.g) * g) >> 8; - state->dest_rgba.b = ((state->dest_rgba.b) * b) >> 8; - - if (state->cmd_set & CMD_SET_ABC_SRC) - state->dest_rgba.a = a; -} - -static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int32_t dx2) -{ - svga_t *svga = &virge->svga; - uint8_t *vram = virge->svga.vram; - - int x_dir = s3d_tri->tlr ? 1 : -1; - - int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE); - - int y_count = yc; - - int bpp = (s3d_tri->cmd_set >> 2) & 7; - - uint32_t dest_offset = 0, z_offset = 0; - - uint32_t src_col; - int src_r = 0, src_g = 0, src_b = 0; - - int x; - int xe; - uint32_t z; - - uint32_t dest_addr, z_addr; - int dx; - int x_offset; - int xz_offset; - - int update; - uint16_t src_z = 0; - - if (s3d_tri->cmd_set & CMD_SET_HC) - { - if (state->y < s3d_tri->clip_t) - return; - if (state->y > s3d_tri->clip_b) - { - int diff_y = state->y - s3d_tri->clip_b; - - if (diff_y > y_count) - diff_y = y_count; - - state->base_u += (s3d_tri->TdUdY * diff_y); - state->base_v += (s3d_tri->TdVdY * diff_y); - state->base_z += (s3d_tri->TdZdY * diff_y); - state->base_r += (s3d_tri->TdRdY * diff_y); - state->base_g += (s3d_tri->TdGdY * diff_y); - state->base_b += (s3d_tri->TdBdY * diff_y); - state->base_a += (s3d_tri->TdAdY * diff_y); - state->base_d += (s3d_tri->TdDdY * diff_y); - state->base_w += (s3d_tri->TdWdY * diff_y); - state->x1 += (dx1 * diff_y); - state->x2 += (dx2 * diff_y); - state->y -= diff_y; - dest_offset -= s3d_tri->dest_str; - z_offset -= s3d_tri->z_str; - y_count -= diff_y; - } - if ((state->y - y_count) < s3d_tri->clip_t) - y_count = state->y - s3d_tri->clip_t; - } - - dest_offset = s3d_tri->dest_base + (state->y * s3d_tri->dest_str); - z_offset = s3d_tri->z_base + (state->y * s3d_tri->z_str); - - for (; y_count > 0; y_count--) - { - x = (state->x1 + ((1 << 20) - 1)) >> 20; - xe = (state->x2 + ((1 << 20) - 1)) >> 20; - z = (state->base_z > 0) ? (state->base_z << 1) : 0; - if (x_dir < 0) - { - x--; - xe--; - } - - if (((x != xe) && ((x_dir > 0) && (x < xe))) || ((x_dir < 0) && (x > xe))) - { - dx = (x_dir > 0) ? ((31 - ((state->x1-1) >> 15)) & 0x1f) : (((state->x1-1) >> 15) & 0x1f); - x_offset = x_dir * (bpp + 1); - xz_offset = x_dir << 1; - if (x_dir > 0) - dx += 1; - state->r = state->base_r + ((s3d_tri->TdRdX * dx) >> 5); - state->g = state->base_g + ((s3d_tri->TdGdX * dx) >> 5); - state->b = state->base_b + ((s3d_tri->TdBdX * dx) >> 5); - state->a = state->base_a + ((s3d_tri->TdAdX * dx) >> 5); - state->u = state->base_u + ((s3d_tri->TdUdX * dx) >> 5); - state->v = state->base_v + ((s3d_tri->TdVdX * dx) >> 5); - state->w = state->base_w + ((s3d_tri->TdWdX * dx) >> 5); - state->d = state->base_d + ((s3d_tri->TdDdX * dx) >> 5); - z += ((s3d_tri->TdZdX * dx) >> 5); - - if (s3d_tri->cmd_set & CMD_SET_HC) - { - if (x_dir > 0) - { - if (x > s3d_tri->clip_r) - goto tri_skip_line; - if (xe < s3d_tri->clip_l) - goto tri_skip_line; - if (xe > s3d_tri->clip_r) - xe = s3d_tri->clip_r; - if (x < s3d_tri->clip_l) - { - int diff_x = s3d_tri->clip_l - x; - - z += (s3d_tri->TdZdX * diff_x); - state->u += (s3d_tri->TdUdX * diff_x); - state->v += (s3d_tri->TdVdX * diff_x); - state->r += (s3d_tri->TdRdX * diff_x); - state->g += (s3d_tri->TdGdX * diff_x); - state->b += (s3d_tri->TdBdX * diff_x); - state->a += (s3d_tri->TdAdX * diff_x); - state->d += (s3d_tri->TdDdX * diff_x); - state->w += (s3d_tri->TdWdX * diff_x); - - x = s3d_tri->clip_l; - } - } - else - { - if (x < s3d_tri->clip_l) - goto tri_skip_line; - if (xe > s3d_tri->clip_r) - goto tri_skip_line; - if (xe < s3d_tri->clip_l) - xe = s3d_tri->clip_l; - if (x > s3d_tri->clip_r) - { - int diff_x = x - s3d_tri->clip_r; - - z += (s3d_tri->TdZdX * diff_x); - state->u += (s3d_tri->TdUdX * diff_x); - state->v += (s3d_tri->TdVdX * diff_x); - state->r += (s3d_tri->TdRdX * diff_x); - state->g += (s3d_tri->TdGdX * diff_x); - state->b += (s3d_tri->TdBdX * diff_x); - state->a += (s3d_tri->TdAdX * diff_x); - state->d += (s3d_tri->TdDdX * diff_x); - state->w += (s3d_tri->TdWdX * diff_x); - - x = s3d_tri->clip_r; - } - } - } - - virge->svga.changedvram[(dest_offset & svga->vram_mask) >> 12] = changeframecount; - - dest_addr = dest_offset + (x * (bpp + 1)); - z_addr = z_offset + (x << 1); - - for (; x != xe; x = (x + x_dir) & 0xfff) - { - update = 1; - _x = x; _y = state->y; - - if (use_z) - { - src_z = Z_READ(z_addr); - Z_CLIP(src_z, z >> 16); - } - - if (update) - { - uint32_t dest_col; - - dest_pixel(state); - - if (s3d_tri->cmd_set & CMD_SET_ABC_ENABLE) - { - switch (bpp) - { - case 0: /*8 bpp*/ - /*Not implemented yet*/ - break; - case 1: /*16 bpp*/ - src_col = *(uint16_t *)&vram[dest_addr & svga->vram_mask]; - RGB15_TO_24(src_col, src_r, src_g, src_b); - break; - case 2: /*24 bpp*/ - src_col = (*(uint32_t *)&vram[dest_addr & svga->vram_mask]) & 0xffffff; - RGB24_TO_24(src_col, src_r, src_g, src_b); - break; - } - - state->dest_rgba.r = ((state->dest_rgba.r * state->dest_rgba.a) + (src_r * (255 - state->dest_rgba.a))) / 255; - state->dest_rgba.g = ((state->dest_rgba.g * state->dest_rgba.a) + (src_g * (255 - state->dest_rgba.a))) / 255; - state->dest_rgba.b = ((state->dest_rgba.b * state->dest_rgba.a) + (src_b * (255 - state->dest_rgba.a))) / 255; - } - - switch (bpp) - { - case 0: /*8 bpp*/ - /*Not implemented yet*/ - break; - case 1: /*16 bpp*/ - RGB15(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, dest_col); - *(uint16_t *)&vram[dest_addr] = dest_col; - break; - case 2: /*24 bpp*/ - dest_col = RGB24(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b); - *(uint8_t *)&vram[dest_addr] = dest_col & 0xff; - *(uint8_t *)&vram[dest_addr + 1] = (dest_col >> 8) & 0xff; - *(uint8_t *)&vram[dest_addr + 2] = (dest_col >> 16) & 0xff; - break; - } - - if (use_z && (s3d_tri->cmd_set & CMD_SET_ZUP)) - Z_WRITE(z_addr, src_z); - } - - z += s3d_tri->TdZdX; - state->u += s3d_tri->TdUdX; - state->v += s3d_tri->TdVdX; - state->r += s3d_tri->TdRdX; - state->g += s3d_tri->TdGdX; - state->b += s3d_tri->TdBdX; - state->a += s3d_tri->TdAdX; - state->d += s3d_tri->TdDdX; - state->w += s3d_tri->TdWdX; - dest_addr += x_offset; - z_addr += xz_offset; - virge->pixel_count++; - } - } -tri_skip_line: - state->x1 += dx1; - state->x2 += dx2; - state->base_u += s3d_tri->TdUdY; - state->base_v += s3d_tri->TdVdY; - state->base_z += s3d_tri->TdZdY; - state->base_r += s3d_tri->TdRdY; - state->base_g += s3d_tri->TdGdY; - state->base_b += s3d_tri->TdBdY; - state->base_a += s3d_tri->TdAdY; - state->base_d += s3d_tri->TdDdY; - state->base_w += s3d_tri->TdWdY; - state->y--; - dest_offset -= s3d_tri->dest_str; - z_offset -= s3d_tri->z_str; - } -} - -static int tex_size[8] = -{ - 4*2, - 2*2, - 2*2, - 1*2, - 2/1, - 2/1, - 1*2, - 1*2 -}; - -static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) -{ - s3d_state_t state; - - uint32_t tex_base; - int c; - - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - - state.tbu = s3d_tri->tbu << 11; - state.tbv = s3d_tri->tbv << 11; - - state.max_d = (s3d_tri->cmd_set >> 8) & 15; - - state.tex_bdr_clr = s3d_tri->tex_bdr_clr; - - state.cmd_set = s3d_tri->cmd_set; - - state.base_u = s3d_tri->tus; - state.base_v = s3d_tri->tvs; - state.base_z = s3d_tri->tzs; - state.base_r = (int32_t)s3d_tri->trs; - state.base_g = (int32_t)s3d_tri->tgs; - state.base_b = (int32_t)s3d_tri->tbs; - state.base_a = (int32_t)s3d_tri->tas; - state.base_d = s3d_tri->tds; - state.base_w = s3d_tri->tws; - - tex_base = s3d_tri->tex_base; - for (c = 9; c >= 0; c--) - { - state.texture[c] = (uint16_t *)&virge->svga.vram[tex_base]; - if (c <= state.max_d) - tex_base += ((1 << (c*2)) * tex_size[(s3d_tri->cmd_set >> 5) & 7]) / 2; - } - - switch ((s3d_tri->cmd_set >> 27) & 0xf) - { - case 0: - dest_pixel = dest_pixel_gouraud_shaded_triangle; - break; - case 1: - case 5: - switch ((s3d_tri->cmd_set >> 15) & 0x3) - { - case 0: - dest_pixel = dest_pixel_lit_texture_reflection; - break; - case 1: - dest_pixel = dest_pixel_lit_texture_modulate; - break; - case 2: - dest_pixel = dest_pixel_lit_texture_decal; - break; - default: - s3_virge_log("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); - return; - } - break; - case 2: - case 6: - dest_pixel = dest_pixel_unlit_texture_triangle; - break; - default: - s3_virge_log("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); - return; - } - - switch (((s3d_tri->cmd_set >> 12) & 7) | ((s3d_tri->cmd_set & (1 << 29)) ? 8 : 0)) - { - case 0: case 1: - tex_sample = tex_sample_mipmap; - break; - case 2: case 3: - tex_sample = virge->bilinear_enabled ? tex_sample_mipmap_filter : tex_sample_mipmap; - break; - case 4: case 5: - tex_sample = tex_sample_normal; - break; - case 6: case 7: - tex_sample = virge->bilinear_enabled ? tex_sample_normal_filter : tex_sample_normal; - break; - case (0 | 8): case (1 | 8): - if (virge->is_375) - tex_sample = tex_sample_persp_mipmap_375; - else - tex_sample = tex_sample_persp_mipmap; - break; - case (2 | 8): case (3 | 8): - if (virge->is_375) - tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter_375 : tex_sample_persp_mipmap_375; - else - tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter : tex_sample_persp_mipmap; - break; - case (4 | 8): case (5 | 8): - if (virge->is_375) - tex_sample = tex_sample_persp_normal_375; - else - tex_sample = tex_sample_persp_normal; - break; - case (6 | 8): case (7 | 8): - if (virge->is_375) - tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter_375 : tex_sample_persp_normal_375; - else - tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal; - break; - } - - switch ((s3d_tri->cmd_set >> 5) & 7) - { - case 0: - tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB8888 : tex_ARGB8888_nowrap; - break; - case 1: - tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB4444 : tex_ARGB4444_nowrap; - break; - case 2: - tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; - break; - default: - s3_virge_log("bad texture type %i\n", (s3d_tri->cmd_set >> 5) & 7); - tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; - break; - } - - state.y = s3d_tri->tys; - state.x1 = s3d_tri->txs; - state.x2 = s3d_tri->txend01; - tri(virge, s3d_tri, &state, s3d_tri->ty01, s3d_tri->TdXdY02, s3d_tri->TdXdY01); - state.x2 = s3d_tri->txend12; - tri(virge, s3d_tri, &state, s3d_tri->ty12, s3d_tri->TdXdY02, s3d_tri->TdXdY12); - - virge->tri_count++; - - end_time = plat_timer_read(); - - virge_time += end_time - start_time; -} - -static void render_thread(void *param) -{ - virge_t *virge = (virge_t *)param; - - while (1) - { - thread_wait_event(virge->wake_render_thread, -1); - thread_reset_event(virge->wake_render_thread); - virge->s3d_busy = 1; - while (!RB_EMPTY) - { - s3_virge_triangle(virge, &virge->s3d_buffer[virge->s3d_read_idx & RB_MASK]); - virge->s3d_read_idx++; - - if (RB_ENTRIES == RB_SIZE - 1) - thread_set_event(virge->not_full_event); - } - virge->s3d_busy = 0; - virge->subsys_stat |= INT_S3D_DONE; - s3_virge_update_irqs(virge); - } -} - -static void queue_triangle(virge_t *virge) -{ - if (RB_FULL) - { - thread_reset_event(virge->not_full_event); - if (RB_FULL) - thread_wait_event(virge->not_full_event, -1); /*Wait for room in ringbuffer*/ - } - virge->s3d_buffer[virge->s3d_write_idx & RB_MASK] = virge->s3d_tri; - virge->s3d_write_idx++; - if (!virge->s3d_busy) - thread_set_event(virge->wake_render_thread); /*Wake up render thread if moving from idle*/ -} - -static void s3_virge_hwcursor_draw(svga_t *svga, int displine) -{ - virge_t *virge = (virge_t *)svga->p; - int x; - uint16_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - uint32_t fg, bg; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; - - switch (svga->bpp) - { - case 15: - fg = video_15to32[virge->hwc_fg_col & 0xffff]; - bg = video_15to32[virge->hwc_bg_col & 0xffff]; - break; - - case 16: - fg = video_16to32[virge->hwc_fg_col & 0xffff]; - bg = video_16to32[virge->hwc_bg_col & 0xffff]; - break; - - case 24: case 32: - fg = virge->hwc_fg_col; - bg = virge->hwc_bg_col; - break; - - default: - fg = svga->pallook[virge->hwc_fg_col & 0xff]; - bg = svga->pallook[virge->hwc_bg_col & 0xff]; - break; - } - - for (x = 0; x < 64; x += 16) - { - dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; - dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; - if (svga->crtc[0x55] & 0x10) - { - /*X11*/ - for (xx = 0; xx < 16; xx++) - { - if (offset >= svga->hwcursor_latch.x) - { - if (dat[0] & 0x8000) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = (dat[1] & 0x8000) ? fg : bg; - } - - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - } - else - { - /*Windows*/ - for (xx = 0; xx < 16; xx++) - { - if (offset >= svga->hwcursor_latch.x) - { - if (!(dat[0] & 0x8000)) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = (dat[1] & 0x8000) ? fg : bg; - else if (dat[1] & 0x8000) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; - } - - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - } - svga->hwcursor_latch.addr += 4; - } - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; -} - -#define DECODE_YCbCr() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 2; c++) \ - { \ - uint8_t y1, y2; \ - int8_t Cr, Cb; \ - int dR, dG, dB; \ - \ - y1 = src[0]; \ - Cr = src[1] - 0x80; \ - y2 = src[2]; \ - Cb = src[3] - 0x80; \ - src += 4; \ - \ - dR = (359*Cr) >> 8; \ - dG = (88*Cb + 183*Cr) >> 8; \ - dB = (453*Cb) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - x_write = (x_write + 2) & 7; \ - } \ - } while (0) - -/*Both YUV formats are untested*/ -#define DECODE_YUV211() \ - do \ - { \ - uint8_t y1, y2, y3, y4; \ - int8_t U, V; \ - int dR, dG, dB; \ - \ - U = src[0] - 0x80; \ - y1 = (298 * (src[1] - 16)) >> 8; \ - y2 = (298 * (src[2] - 16)) >> 8; \ - V = src[3] - 0x80; \ - y3 = (298 * (src[4] - 16)) >> 8; \ - y4 = (298 * (src[5] - 16)) >> 8; \ - src += 6; \ - \ - dR = (309*V) >> 8; \ - dG = (100*U + 208*V) >> 8; \ - dB = (516*U) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - r[x_write+2] = y3 + dR; \ - CLAMP(r[x_write+2]); \ - g[x_write+2] = y3 - dG; \ - CLAMP(g[x_write+2]); \ - b[x_write+2] = y3 + dB; \ - CLAMP(b[x_write+2]); \ - \ - r[x_write+3] = y4 + dR; \ - CLAMP(r[x_write+3]); \ - g[x_write+3] = y4 - dG; \ - CLAMP(g[x_write+3]); \ - b[x_write+3] = y4 + dB; \ - CLAMP(b[x_write+3]); \ - \ - x_write = (x_write + 4) & 7; \ - } while (0) - -#define DECODE_YUV422() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 2; c++) \ - { \ - uint8_t y1, y2; \ - int8_t U, V; \ - int dR, dG, dB; \ - \ - U = src[0] - 0x80; \ - y1 = (298 * (src[1] - 16)) >> 8; \ - V = src[2] - 0x80; \ - y2 = (298 * (src[3] - 16)) >> 8; \ - src += 4; \ - \ - dR = (309*V) >> 8; \ - dG = (100*U + 208*V) >> 8; \ - dB = (516*U) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - x_write = (x_write + 2) & 7; \ - } \ - } while (0) - -#define DECODE_RGB555() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - uint16_t dat; \ - \ - dat = *(uint16_t *)src; \ - src += 2; \ - \ - r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ - g[x_write + c] = ((dat & 0x03e0) >> 2) | ((dat & 0x03e0) >> 7); \ - b[x_write + c] = ((dat & 0x7c00) >> 7) | ((dat & 0x7c00) >> 12); \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) - -#define DECODE_RGB565() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - uint16_t dat; \ - \ - dat = *(uint16_t *)src; \ - src += 2; \ - \ - r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ - g[x_write + c] = ((dat & 0x07e0) >> 3) | ((dat & 0x07e0) >> 9); \ - b[x_write + c] = ((dat & 0xf800) >> 8) | ((dat & 0xf800) >> 13); \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) - -#define DECODE_RGB888() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - r[x_write + c] = src[0]; \ - g[x_write + c] = src[1]; \ - b[x_write + c] = src[2]; \ - src += 3; \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) - -#define DECODE_XRGB8888() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - r[x_write + c] = src[0]; \ - g[x_write + c] = src[1]; \ - b[x_write + c] = src[2]; \ - src += 4; \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) - -#define OVERLAY_SAMPLE() \ - do \ - { \ - switch (virge->streams.sdif) \ - { \ - case 1: \ - DECODE_YCbCr(); \ - break; \ - case 2: \ - DECODE_YUV422(); \ - break; \ - case 3: \ - DECODE_RGB555(); \ - break; \ - case 4: \ - DECODE_YUV211(); \ - break; \ - case 5: \ - DECODE_RGB565(); \ - break; \ - case 6: \ - DECODE_RGB888(); \ - break; \ - case 7: \ - default: \ - DECODE_XRGB8888(); \ - break; \ - } \ - } while (0) - -static void s3_virge_overlay_draw(svga_t *svga, int displine) -{ - virge_t *virge = (virge_t *)svga->p; - int offset = (virge->streams.sec_x - virge->streams.pri_x) + 1; - int h_acc = virge->streams.dda_horiz_accumulator; - int r[8], g[8], b[8]; - int x_size, x_read = 4, x_write = 4; - int x; - uint32_t *p; - uint8_t *src = &svga->vram[svga->overlay_latch.addr]; - int y_add = enable_overscan ? 16 : 0; - int x_add = enable_overscan ? 8 : 0; - - p = &((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add]; - - if ((offset + virge->streams.sec_w) > virge->streams.pri_w) - x_size = (virge->streams.pri_w - virge->streams.sec_x) + 1; - else - x_size = virge->streams.sec_w + 1; - - OVERLAY_SAMPLE(); - - for (x = 0; x < x_size; x++) - { - *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); - - h_acc += virge->streams.k1_horiz_scale; - if (h_acc >= 0) - { - if ((x_read ^ (x_read + 1)) & ~3) - OVERLAY_SAMPLE(); - x_read = (x_read + 1) & 7; - - h_acc += (virge->streams.k2_horiz_scale - virge->streams.k1_horiz_scale); - } - } - - svga->overlay_latch.v_acc += virge->streams.k1_vert_scale; - if (svga->overlay_latch.v_acc >= 0) - { - svga->overlay_latch.v_acc += (virge->streams.k2_vert_scale - virge->streams.k1_vert_scale); - svga->overlay_latch.addr += virge->streams.sec_stride; - } -} - -static uint8_t s3_virge_pci_read(int func, int addr, void *p) -{ - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - uint8_t ret = 0; - switch (addr) - { - case 0x00: ret = 0x33; break; /*'S3'*/ - case 0x01: ret = 0x53; break; - - case 0x02: ret = virge->virge_id_low; break; - case 0x03: ret = virge->virge_id_high; break; - - case 0x04: ret = virge->pci_regs[0x04] & 0x27; break; - - case 0x07: ret = virge->pci_regs[0x07] & 0x36; break; - - case 0x08: ret = 0; break; /*Revision ID*/ - case 0x09: ret = 0; break; /*Programming interface*/ - - case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ - case 0x0b: ret = 0x03; /*output = 3; */break; - - case 0x0d: ret = virge->pci_regs[0x0d] & 0xf8; break; - - case 0x10: ret = 0x00; break;/*Linear frame buffer address*/ - case 0x11: ret = 0x00; break; - case 0x12: ret = 0x00; break; - case 0x13: ret = svga->crtc[0x59] & 0xfc; break; - - case 0x30: ret = virge->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/ - case 0x31: ret = 0x00; break; - case 0x32: ret = virge->pci_regs[0x32]; break; - case 0x33: ret = virge->pci_regs[0x33]; break; - - case 0x3c: ret = virge->pci_regs[0x3c]; break; - - case 0x3d: ret = 0x01; break; /*INTA*/ - - case 0x3e: ret = 0x04; break; - case 0x3f: ret = 0xff; break; - - } - return ret; -} - -static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) -{ - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - switch (addr) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x3d: case 0x3e: case 0x3f: - return; - - case PCI_REG_COMMAND: - if (val & PCI_COMMAND_IO) - { - io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - } - else - io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - virge->pci_regs[PCI_REG_COMMAND] = val & 0x27; - s3_virge_updatemapping(virge); - return; - case 0x07: - virge->pci_regs[0x07] = val & 0x3e; - return; - case 0x0d: - virge->pci_regs[0x0d] = val & 0xf8; - return; - - case 0x13: - svga->crtc[0x59] = val & 0xfc; - s3_virge_updatemapping(virge); - return; - - case 0x30: case 0x32: case 0x33: - virge->pci_regs[addr] = val; - if (virge->pci_regs[0x30] & 0x01) - { - uint32_t addr = (virge->pci_regs[0x32] << 16) | (virge->pci_regs[0x33] << 24); - mem_mapping_set_addr(&virge->bios_rom.mapping, addr, 0x8000); - mem_mapping_enable(&virge->bios_rom.mapping); - } - else - { - mem_mapping_disable(&virge->bios_rom.mapping); - } - return; - case 0x3c: - virge->pci_regs[0x3c] = val; - return; - } -} - -static void *s3_virge_init(const device_t *info) -{ - virge_t *virge = malloc(sizeof(virge_t)); - memset(virge, 0, sizeof(virge_t)); - - virge->bilinear_enabled = device_get_config_int("bilinear"); - virge->dithering_enabled = device_get_config_int("dithering"); - virge->memory_size = device_get_config_int("memory"); - - svga_init(&virge->svga, virge, virge->memory_size << 20, - s3_virge_recalctimings, - s3_virge_in, s3_virge_out, - s3_virge_hwcursor_draw, - s3_virge_overlay_draw); - virge->svga.vblank_start = s3_virge_vblank_start; - - virge->pci = !!(info->flags & DEVICE_PCI); - - rom_init(&virge->bios_rom, L"roms/video/s3virge/s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (info->flags & DEVICE_PCI) - mem_mapping_disable(&virge->bios_rom.mapping); - - mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, - s3_virge_mmio_read_w, - s3_virge_mmio_read_l, - s3_virge_mmio_write, - s3_virge_mmio_write_w, - s3_virge_mmio_write_l, - NULL, - 0, - virge); - mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, - s3_virge_mmio_read_w, - s3_virge_mmio_read_l, - s3_virge_mmio_write, - s3_virge_mmio_write_w, - s3_virge_mmio_write_l, - NULL, - 0, - virge); - mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - 0, - &virge->svga); - - io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - - virge->pci_regs[4] = 3; - virge->pci_regs[5] = 0; - virge->pci_regs[6] = 0; - virge->pci_regs[7] = 2; - virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; - virge->pci_regs[0x3e] = 4; - virge->pci_regs[0x3f] = 0xff; - - virge->virge_id_high = 0x56; - virge->virge_id_low = 0x31; - virge->virge_rev = 0; - virge->virge_id = 0xe1; - - switch (virge->memory_size) - { - case 2: - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); - break; - case 4: - default: - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); - break; - } - - virge->svga.crtc[0x37] = 1; - virge->svga.crtc[0x53] = 1 << 3; - virge->svga.crtc[0x59] = 0x70; - - virge->is_375 = 0; - - if (info->flags & DEVICE_PCI) - { - virge->card = pci_add_card(PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); - } - - virge->wake_render_thread = thread_create_event(); - virge->wake_main_thread = thread_create_event(); - virge->not_full_event = thread_create_event(); - virge->render_thread = thread_create(render_thread, virge); - - virge->wake_fifo_thread = thread_create_event(); - virge->fifo_not_full_event = thread_create_event(); - virge->fifo_thread = thread_create(fifo_thread, virge); - - return virge; -} - -static void *s3_virge_988_init(const device_t *info) -{ - virge_t *virge = malloc(sizeof(virge_t)); - memset(virge, 0, sizeof(virge_t)); - - virge->bilinear_enabled = device_get_config_int("bilinear"); - virge->dithering_enabled = device_get_config_int("dithering"); - virge->memory_size = device_get_config_int("memory"); - - svga_init(&virge->svga, virge, virge->memory_size << 20, - s3_virge_recalctimings, - s3_virge_in, s3_virge_out, - s3_virge_hwcursor_draw, - s3_virge_overlay_draw); - - virge->pci = !!(info->flags & DEVICE_PCI); - - rom_init(&virge->bios_rom, L"roms/video/s3virge/diamondstealth3000.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (info->flags & DEVICE_PCI) - mem_mapping_disable(&virge->bios_rom.mapping); - - mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, - s3_virge_mmio_read_w, - s3_virge_mmio_read_l, - s3_virge_mmio_write, - s3_virge_mmio_write_w, - s3_virge_mmio_write_l, - NULL, - 0, - virge); - mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, - s3_virge_mmio_read_w, - s3_virge_mmio_read_l, - s3_virge_mmio_write, - s3_virge_mmio_write_w, - s3_virge_mmio_write_l, - NULL, - 0, - virge); - mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - 0, - &virge->svga); - - io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - - virge->pci_regs[4] = 3; - virge->pci_regs[5] = 0; - virge->pci_regs[6] = 0; - virge->pci_regs[7] = 2; - virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; - virge->pci_regs[0x3e] = 4; - virge->pci_regs[0x3f] = 0xff; - - virge->virge_id_high = 0x88; - virge->virge_id_low = 0x3d; - virge->virge_rev = 0; - virge->virge_id = 0xe1; - - switch (virge->memory_size) - { - case 2: - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); - break; - case 4: - default: - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); - break; - } - - virge->svga.crtc[0x37] = 1; - virge->svga.crtc[0x53] = 1 << 3; - virge->svga.crtc[0x59] = 0x70; - - virge->is_375 = 0; - - if (info->flags & DEVICE_PCI) - { - virge->card = pci_add_card(PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); - } - - virge->wake_render_thread = thread_create_event(); - virge->wake_main_thread = thread_create_event(); - virge->not_full_event = thread_create_event(); - virge->render_thread = thread_create(render_thread, virge); - - virge->wake_fifo_thread = thread_create_event(); - virge->fifo_not_full_event = thread_create_event(); - virge->fifo_thread = thread_create(fifo_thread, virge); - - return virge; -} - -static void *s3_virge_375_init(const device_t *info, wchar_t *romfn) -{ - virge_t *virge = malloc(sizeof(virge_t)); - memset(virge, 0, sizeof(virge_t)); - - virge->bilinear_enabled = device_get_config_int("bilinear"); - virge->dithering_enabled = device_get_config_int("dithering"); - virge->memory_size = device_get_config_int("memory"); - - svga_init(&virge->svga, virge, virge->memory_size << 20, - s3_virge_recalctimings, - s3_virge_in, s3_virge_out, - s3_virge_hwcursor_draw, - s3_virge_overlay_draw); - - virge->pci = !!(info->flags & DEVICE_PCI); - - rom_init(&virge->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (info->flags & DEVICE_PCI) - mem_mapping_disable(&virge->bios_rom.mapping); - - mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, - s3_virge_mmio_read_w, - s3_virge_mmio_read_l, - s3_virge_mmio_write, - s3_virge_mmio_write_w, - s3_virge_mmio_write_l, - NULL, - 0, - virge); - mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, - s3_virge_mmio_read_w, - s3_virge_mmio_read_l, - s3_virge_mmio_write, - s3_virge_mmio_write_w, - s3_virge_mmio_write_l, - NULL, - 0, - virge); - mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - 0, - &virge->svga); - - io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - - virge->pci_regs[4] = 3; - virge->pci_regs[5] = 0; - virge->pci_regs[6] = 0; - virge->pci_regs[7] = 2; - virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; - virge->pci_regs[0x3e] = 4; - virge->pci_regs[0x3f] = 0xff; - - virge->virge_id_high = 0x8a; - virge->virge_id_low = 0x01; - virge->virge_rev = 0; - virge->virge_id = 0xe1; - - switch (virge->memory_size) - { - case 2: - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); - break; - case 4: - default: - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); - break; - } - virge->svga.crtc[0x37] = 1; - virge->svga.crtc[0x53] = 1 << 3; - virge->svga.crtc[0x59] = 0x70; - - virge->svga.crtc[0x6c] = 0x01; - - virge->is_375 = 1; - - if (info->flags & DEVICE_PCI) - { - virge->card = pci_add_card(PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); - } - - virge->wake_render_thread = thread_create_event(); - virge->wake_main_thread = thread_create_event(); - virge->not_full_event = thread_create_event(); - virge->render_thread = thread_create(render_thread, virge); - - virge->wake_fifo_thread = thread_create_event(); - virge->fifo_not_full_event = thread_create_event(); - virge->fifo_thread = thread_create(fifo_thread, virge); - - return virge; -} - -static void *s3_virge_375_1_init(const device_t *info) -{ - return s3_virge_375_init(info, L"roms/video/s3virge/86c375_1.bin"); -} - -static void *s3_virge_375_4_init(const device_t *info) -{ - return s3_virge_375_init(info, L"roms/video/s3virge/86c375_4.bin"); -} - -static void s3_virge_close(void *p) -{ - virge_t *virge = (virge_t *)p; -#if 0 - FILE *f = fopen("vram.dmp", "wb"); - fwrite(virge->svga.vram, 4 << 20, 1, f); - fclose(f); -#endif - - thread_kill(virge->render_thread); - thread_destroy_event(virge->not_full_event); - thread_destroy_event(virge->wake_main_thread); - thread_destroy_event(virge->wake_render_thread); - - thread_kill(virge->fifo_thread); - thread_destroy_event(virge->wake_fifo_thread); - thread_destroy_event(virge->fifo_not_full_event); - - svga_close(&virge->svga); - - free(virge); -} - -static int s3_virge_available(void) -{ - return rom_present(L"roms/video/s3virge/s3virge.bin"); -} - -static int s3_virge_988_available(void) -{ - return rom_present(L"roms/video/s3virge/diamondstealth3000.vbi"); -} - -static int s3_virge_375_1_available(void) -{ - return rom_present(L"roms/video/s3virge/86c375_1.bin"); -} - -static int s3_virge_375_4_available(void) -{ - return rom_present(L"roms/video/s3virge/86c375_4.bin"); -} - -static void s3_virge_speed_changed(void *p) -{ - virge_t *virge = (virge_t *)p; - - svga_recalctimings(&virge->svga); -} - -static void s3_virge_force_redraw(void *p) -{ - virge_t *virge = (virge_t *)p; - - virge->svga.fullchange = changeframecount; -} - -static const device_config_t s3_virge_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, - { - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "" - } - } - }, - { - "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 - }, - { - "dithering", "Dithering", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } -}; - -const device_t s3_virge_vlb_device = -{ - "Diamond Stealth 3D 2000 (S3 ViRGE) VLB", - DEVICE_VLB, - 0, - s3_virge_init, - s3_virge_close, - NULL, - s3_virge_available, - s3_virge_speed_changed, - s3_virge_force_redraw, - s3_virge_config -}; - -const device_t s3_virge_pci_device = -{ - "Diamond Stealth 3D 2000 (S3 ViRGE) PCI", - DEVICE_PCI, - 0, - s3_virge_init, - s3_virge_close, - NULL, - s3_virge_available, - s3_virge_speed_changed, - s3_virge_force_redraw, - s3_virge_config -}; - -const device_t s3_virge_988_vlb_device = -{ - "Diamond Stealth 3D 3000 (S3 ViRGE/VX) VLB", - DEVICE_VLB, - 0, - s3_virge_988_init, - s3_virge_close, - NULL, - s3_virge_988_available, - s3_virge_speed_changed, - s3_virge_force_redraw, - s3_virge_config -}; - -const device_t s3_virge_988_pci_device = -{ - "Diamond Stealth 3D 3000 (S3 ViRGE/VX) PCI", - DEVICE_PCI, - 0, - s3_virge_988_init, - s3_virge_close, - NULL, - s3_virge_988_available, - s3_virge_speed_changed, - s3_virge_force_redraw, - s3_virge_config -}; - -const device_t s3_virge_375_vlb_device = -{ - "S3 ViRGE/DX VLB", - DEVICE_VLB, - 0, - s3_virge_375_1_init, - s3_virge_close, - NULL, - s3_virge_375_1_available, - s3_virge_speed_changed, - s3_virge_force_redraw, - s3_virge_config -}; - -const device_t s3_virge_375_pci_device = -{ - "S3 ViRGE/DX PCI", - DEVICE_PCI, - 0, - s3_virge_375_1_init, - s3_virge_close, - NULL, - s3_virge_375_1_available, - s3_virge_speed_changed, - s3_virge_force_redraw, - s3_virge_config -}; - -const device_t s3_virge_375_4_vlb_device = -{ - "S3 ViRGE/DX (VBE 2.0) VLB", - DEVICE_VLB, - 0, - s3_virge_375_4_init, - s3_virge_close, - NULL, - s3_virge_375_4_available, - s3_virge_speed_changed, - s3_virge_force_redraw, - s3_virge_config -}; - -const device_t s3_virge_375_4_pci_device = -{ - "S3 ViRGE/DX (VBE 2.0) PCI", - DEVICE_PCI, - 0, - s3_virge_375_4_init, - s3_virge_close, - NULL, - s3_virge_375_4_available, - s3_virge_speed_changed, - s3_virge_force_redraw, - s3_virge_config -}; diff --git a/backup code/video - Cópia/vid_s3_virge.h b/backup code/video - Cópia/vid_s3_virge.h deleted file mode 100644 index 2d340f649..000000000 --- a/backup code/video - Cópia/vid_s3_virge.h +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t s3_virge_vlb_device; -extern const device_t s3_virge_pci_device; -extern const device_t s3_virge_988_vlb_device; -extern const device_t s3_virge_988_pci_device; -extern const device_t s3_virge_375_vlb_device; -extern const device_t s3_virge_375_pci_device; -extern const device_t s3_virge_375_4_vlb_device; -extern const device_t s3_virge_375_4_pci_device; diff --git a/backup code/video - Cópia/vid_sc1502x_ramdac.c b/backup code/video - Cópia/vid_sc1502x_ramdac.c deleted file mode 100644 index 18f78c8b0..000000000 --- a/backup code/video - Cópia/vid_sc1502x_ramdac.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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 a Sierra SC1502X RAMDAC. - * - * Used by the TLIVESA1 driver for ET4000. - * - * Version: @(#)vid_sc1502x_ramdac.c 1.0.2 2017/11/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_sc1502x_ramdac.h" - - -void sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga) -{ - int oldbpp = 0; - switch (addr) - { - case 0x3C6: - if (ramdac->state == 4) - { - ramdac->state = 0; - if (val == 0xFF) break; - ramdac->ctrl = val; - oldbpp = svga->bpp; - switch ((val&1)|((val&0xC0)>>5)) - { - case 0: - svga->bpp = 8; - break; - case 2: case 3: - switch (val & 0x20) - { - case 0x00: svga->bpp = 32; break; - case 0x20: svga->bpp = 24; break; - } - break; - case 4: case 5: - svga->bpp = 15; - break; - case 6: - svga->bpp = 16; - break; - case 7: - switch (val & 4) - { - case 4: - switch (val & 0x20) - { - case 0x00: svga->bpp = 32; break; - case 0x20: svga->bpp = 24; break; - } - break; - case 0: default: - svga->bpp = 16; - break; - } - case 1: default: - break; - } - if (oldbpp != svga->bpp) - { - svga_recalctimings(svga); - } - return; - } - ramdac->state = 0; - break; - case 0x3C7: case 0x3C8: case 0x3C9: - ramdac->state = 0; - break; - } - svga_out(addr, val, svga); -} - -uint8_t sc1502x_ramdac_in(uint16_t addr, sc1502x_ramdac_t *ramdac, svga_t *svga) -{ - switch (addr) - { - case 0x3C6: - if (ramdac->state == 4) - { - ramdac->state = 0; - return ramdac->ctrl; - } - ramdac->state++; - break; - case 0x3C7: case 0x3C8: case 0x3C9: - ramdac->state = 0; - break; - } - return svga_in(addr, svga); -} diff --git a/backup code/video - Cópia/vid_sc1502x_ramdac.h b/backup code/video - Cópia/vid_sc1502x_ramdac.h deleted file mode 100644 index 2aaccb391..000000000 --- a/backup code/video - Cópia/vid_sc1502x_ramdac.h +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -typedef struct unk_ramdac_t -{ - int state; - uint8_t ctrl; -} sc1502x_ramdac_t; - -void sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga); -uint8_t sc1502x_ramdac_in(uint16_t addr, sc1502x_ramdac_t *ramdac, svga_t *svga); diff --git a/backup code/video - Cópia/vid_sdac_ramdac.c b/backup code/video - Cópia/vid_sdac_ramdac.c deleted file mode 100644 index 95742e26a..000000000 --- a/backup code/video - Cópia/vid_sdac_ramdac.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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. - * - * 87C716 'SDAC' true colour RAMDAC emulation. - * - * Version: @(#)vid_sdac_ramdac.c 1.0.3 2018/03/21 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_sdac_ramdac.h" - -static void sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) -{ - ramdac->command = val; - switch (val >> 4) - { - case 0x2: case 0x3: case 0xa: svga->bpp = 15; break; - case 0x4: case 0xe: svga->bpp = 24; break; - case 0x5: case 0x6: case 0xc: svga->bpp = 16; break; - case 0x7: svga->bpp = 32; break; - - case 0: case 1: default: svga->bpp = 8; break; - } -} - -static void sdac_reg_write(sdac_ramdac_t *ramdac, int reg, uint8_t val) -{ - if ((reg >= 2 && reg <= 7) || (reg == 0xa) || (reg == 0xe)) - { - if (!ramdac->reg_ff) - ramdac->regs[reg] = (ramdac->regs[reg] & 0xff00) | val; - else - ramdac->regs[reg] = (ramdac->regs[reg] & 0x00ff) | (val << 8); - } - ramdac->reg_ff = !ramdac->reg_ff; - if (!ramdac->reg_ff) - ramdac->windex++; -} - -static uint8_t sdac_reg_read(sdac_ramdac_t *ramdac, int reg) -{ - uint8_t temp; - - if (!ramdac->reg_ff) - temp = ramdac->regs[reg] & 0xff; - else - temp = ramdac->regs[reg] >> 8; - ramdac->reg_ff = !ramdac->reg_ff; - if (!ramdac->reg_ff) - ramdac->rindex++; - - return temp; -} - -void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga) -{ - switch (addr) - { - case 2: - if (ramdac->magic_count == 4) - sdac_control_write(ramdac, svga, val); - ramdac->magic_count = 0; - break; - - case 3: - ramdac->magic_count = 0; - break; - case 0: - ramdac->magic_count = 0; - break; - case 1: - ramdac->magic_count = 0; - break; - - case 4: - ramdac->windex = val; - ramdac->reg_ff = 0; - break; - case 5: - sdac_reg_write(ramdac, ramdac->windex & 0xff, val); - break; - case 6: - sdac_control_write(ramdac, svga, val); - break; - case 7: - ramdac->rindex = val; - ramdac->reg_ff = 0; - break; - } - if (!(addr & 4)) - { - if (addr < 2) - svga_out(addr + 0x3c8, val, svga); - else - svga_out(addr + 0x3c4, val, svga); - } -} - -uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) -{ - uint8_t temp; - switch (addr) - { - case 2: - if (ramdac->magic_count < 5) - ramdac->magic_count++; - if (ramdac->magic_count == 4) - { - temp = 0x70; /*SDAC ID*/ - ramdac->rs2 = 1; - } - if (ramdac->magic_count == 5) - { - temp = ramdac->command; - ramdac->magic_count = 0; - } - return temp; - case 3: - ramdac->magic_count=0; - break; - case 0: - ramdac->magic_count=0; - break; - case 1: - ramdac->magic_count=0; - break; - - case 4: - return ramdac->windex; - case 5: - return sdac_reg_read(ramdac, ramdac->rindex & 0xff); - case 6: - return ramdac->command; - case 7: - return ramdac->rindex; - } - if (!(addr & 4)) - { - if (addr < 2) - return svga_in(addr + 0x3c8, svga); - else - return svga_in(addr + 0x3c4, svga); - } - return 0xff; -} - -float sdac_getclock(int clock, void *p) -{ - sdac_ramdac_t *ramdac = (sdac_ramdac_t *)p; - float t; - int m, n1, n2; - if (clock == 0) return 25175000.0; - if (clock == 1) return 28322000.0; - clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ - m = (ramdac->regs[clock] & 0x7f) + 2; - n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2; - n2 = ((ramdac->regs[clock] >> 13) & 0x07); - t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); - return t; -} - -void sdac_init(sdac_ramdac_t *ramdac) -{ - ramdac->regs[0] = 0x6128; - ramdac->regs[1] = 0x623d; -} diff --git a/backup code/video - Cópia/vid_sdac_ramdac.h b/backup code/video - Cópia/vid_sdac_ramdac.h deleted file mode 100644 index 52d908599..000000000 --- a/backup code/video - Cópia/vid_sdac_ramdac.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -typedef struct sdac_ramdac_t -{ - int magic_count; - uint8_t command; - int windex, rindex; - uint16_t regs[256]; - int reg_ff; - int rs2; -} sdac_ramdac_t; - -void sdac_init(sdac_ramdac_t *ramdac); - -void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga); -uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga); - -float sdac_getclock(int clock, void *p); diff --git a/backup code/video - Cópia/vid_stg_ramdac.c b/backup code/video - Cópia/vid_stg_ramdac.c deleted file mode 100644 index 37b1b5a2a..000000000 --- a/backup code/video - Cópia/vid_stg_ramdac.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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. - * - * STG1702 true colour RAMDAC emulation. - * - * Version: @(#)vid_stg_ramdac.c 1.0.4 2018/01/25 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_stg_ramdac.h" - - -static int stg_state_read[2][8] = {{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}}; -static int stg_state_write[8] = {0,0,0,0,0,6,7,7}; - - -void stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) -{ - if (ramdac->command & 0x8) - { - switch (ramdac->regs[3]) - { - case 0: case 5: case 7: svga->bpp = 8; break; - case 1: case 2: case 8: svga->bpp = 15; break; - case 3: case 6: svga->bpp = 16; break; - case 4: case 9: svga->bpp = 24; break; - default: svga->bpp = 8; break; - } - } - else - { - switch (ramdac->command >> 5) - { - case 0: svga->bpp = 8; break; - case 5: svga->bpp = 15; break; - case 6: svga->bpp = 16; break; - case 7: svga->bpp = 24; break; - default: svga->bpp = 8; break; - } - } - svga_recalctimings(svga); -} - -void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga) -{ - int didwrite, old; - switch (addr) - { - case 0x3c6: - switch (ramdac->magic_count) - { - /* 0 = PEL mask register */ - case 0: case 1: case 2: case 3: - break; - case 4: /* REG06 */ - old = ramdac->command; - ramdac->command = val; - if ((old ^ val) & 8) - { - stg_ramdac_set_bpp(svga, ramdac); - } - else - { - if ((old ^ val) & 0xE0) - { - stg_ramdac_set_bpp(svga, ramdac); - } - } - break; - case 5: - ramdac->index = (ramdac->index & 0xff00) | val; - break; - case 6: - ramdac->index = (ramdac->index & 0xff) | (val << 8); - break; - case 7: - if (ramdac->index < 0x100) - { - ramdac->regs[ramdac->index] = val; - } - if ((ramdac->index == 3) && (ramdac->command & 8)) stg_ramdac_set_bpp(svga, ramdac); - ramdac->index++; - break; - } - didwrite = (ramdac->magic_count >= 4); - ramdac->magic_count = stg_state_write[ramdac->magic_count & 7]; - if (didwrite) return; - break; - case 0x3c7: case 0x3c8: case 0x3c9: - ramdac->magic_count=0; - break; - } - svga_out(addr, val, svga); -} - -uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga) -{ - uint8_t temp = 0xff; - switch (addr) - { - case 0x3c6: - switch (ramdac->magic_count) - { - case 0: case 1: case 2: case 3: - temp = 0xff; - break; - case 4: - temp = ramdac->command; - break; - case 5: - temp = ramdac->index & 0xff; - break; - case 6: - temp = ramdac->index >> 8; - break; - case 7: - switch (ramdac->index) - { - case 0: - temp = 0x44; - break; - case 1: - temp = 0x03; - break; - case 7: - temp = 0x88; - break; - default: - if (ramdac->index < 0x100) temp = ramdac->regs[ramdac->index]; - else temp = 0xff; - break; - } - ramdac->index++; - break; - } - ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7]; - return temp; - case 0x3c7: case 0x3c8: case 0x3c9: - ramdac->magic_count=0; - break; - } - return svga_in(addr, svga); -} - -float stg_getclock(int clock, void *p) -{ - stg_ramdac_t *ramdac = (stg_ramdac_t *)p; - float t; - int m, n, n2; - float b, n1, d; - uint16_t *c; - if (clock == 0) return 25175000.0; - if (clock == 1) return 28322000.0; - clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ - c = (uint16_t *) &ramdac->regs[0x20 + (clock << 1)]; - m = (*c & 0xff) + 2; /* B+2 */ - n = ((*c >> 8) & 0x1f) + 2; /* N1+2 */ - n2 = ((*c >> 13) & 0x07); /* D */ - b = (float) m; - n1 = (float) n; - d = (double) (1 << n2); - t = (14318184.0 * (b / d)) / n1; - return t; -} diff --git a/backup code/video - Cópia/vid_stg_ramdac.h b/backup code/video - Cópia/vid_stg_ramdac.h deleted file mode 100644 index 8e383ea17..000000000 --- a/backup code/video - Cópia/vid_stg_ramdac.h +++ /dev/null @@ -1,14 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -typedef struct stg_ramdac_t -{ - int magic_count; - uint8_t command; - int index; - uint8_t regs[256]; -} stg_ramdac_t; - -void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga); -uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga); -float stg_getclock(int clock, void *p); diff --git a/backup code/video - Cópia/vid_svga.c b/backup code/video - Cópia/vid_svga.c deleted file mode 100644 index 894ab57f3..000000000 --- a/backup code/video - Cópia/vid_svga.c +++ /dev/null @@ -1,1353 +0,0 @@ -/* - * 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. - * - * Generic SVGA handling. - * - * This is intended to be used by another SVGA driver, - * and not as a card in it's own right. - * - * Version: @(#)vid_svga.c 1.0.30 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_svga_render.h" - - -#define svga_output 0 - -void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga); - -extern int cyc_total; -extern uint8_t edatlookup[4][4]; - -uint8_t svga_rotate[8][256]; - -static const uint32_t mask16[16] = { - 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff, - 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff, - 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff, - 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff -}; - -/*Primary SVGA device. As multiple video cards are not yet supported this is the - only SVGA device.*/ -static svga_t *svga_pri; - - -svga_t -*svga_get_pri() -{ - return svga_pri; -} - - -void -svga_set_override(svga_t *svga, int val) -{ - if (svga->override && !val) - svga->fullchange = changeframecount; - svga->override = val; -} - - -/* Used to add custom write modes, eg. by the CL-GD 54xx to add write modes 4 and 5. */ -void -svga_set_ven_write(svga_t *svga, void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr)) -{ - svga->ven_write = ven_write; -} - - -void -svga_out(uint16_t addr, uint8_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - int c; - uint8_t o; - - switch (addr) { - case 0x3c0: - case 0x3c1: - if (!svga->attrff) { - svga->attraddr = val & 31; - if ((val & 0x20) != svga->attr_palette_enable) { - svga->fullchange = 3; - svga->attr_palette_enable = val & 0x20; - svga_recalctimings(svga); - } - } else { - o = svga->attrregs[svga->attraddr & 31]; - svga->attrregs[svga->attraddr & 31] = val; - if (svga->attraddr < 16) - svga->fullchange = changeframecount; - if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { - for (c = 0; c < 16; c++) { - if (svga->attrregs[0x10] & 0x80) { - svga->egapal[c] = (svga->attrregs[c] & 0xf) | - ((svga->attrregs[0x14] & 0xf) << 4); - } else { - svga->egapal[c] = (svga->attrregs[c] & 0x3f) | - ((svga->attrregs[0x14] & 0xc) << 4); - } - } - } - /* Recalculate timings on change of attribute register 0x11 - (overscan border color) too. */ - if (svga->attraddr == 0x10) { - if (o != val) - svga_recalctimings(svga); - } else if (svga->attraddr == 0x11) { - svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; - if (o != val) - svga_recalctimings(svga); - } else if (svga->attraddr == 0x12) { - if ((val & 0xf) != svga->plane_mask) - svga->fullchange = changeframecount; - svga->plane_mask = val & 0xf; - } - } - svga->attrff ^= 1; - break; - case 0x3c2: - svga->miscout = val; - svga->vidclock = val & 4; - io_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); - if (!(val & 1)) - io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); - svga_recalctimings(svga); - break; - case 0x3c4: - svga->seqaddr = val; - break; - case 0x3c5: - if (svga->seqaddr > 0xf) - return; - o = svga->seqregs[svga->seqaddr & 0xf]; - svga->seqregs[svga->seqaddr & 0xf] = val; - if (o != val && (svga->seqaddr & 0xf) == 1) - svga_recalctimings(svga); - switch (svga->seqaddr & 0xf) { - case 1: - if (svga->scrblank && !(val & 0x20)) - svga->fullchange = 3; - svga->scrblank = (svga->scrblank & ~0x20) | (val & 0x20); - svga_recalctimings(svga); - break; - case 2: - svga->writemask = val & 0xf; - break; - case 3: - svga->charsetb = (((val >> 2) & 3) * 0x10000) + 2; - svga->charseta = ((val & 3) * 0x10000) + 2; - if (val & 0x10) - svga->charseta += 0x8000; - if (val & 0x20) - svga->charsetb += 0x8000; - break; - case 4: - svga->chain2_write = !(val & 4); - svga->chain4 = val & 8; - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - !svga->gdcreg[1]) && svga->chain4; - break; - } - break; - case 0x3c6: - svga->dac_mask = val; - break; - case 0x3C7: - svga->dac_read = val; - svga->dac_pos = 0; - break; - case 0x3c8: - svga->dac_write = val; - svga->dac_read = val - 1; - svga->dac_pos = 0; - break; - case 0x3c9: - 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: - svga->vgapal[svga->dac_write].r = svga->dac_r; - svga->vgapal[svga->dac_write].g = svga->dac_g; - svga->vgapal[svga->dac_write].b = val; - if (svga->ramdac_type == RAMDAC_8BIT) - svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r, svga->vgapal[svga->dac_write].g, svga->vgapal[svga->dac_write].b); - else - svga->pallook[svga->dac_write] = makecol32(video_6to8[svga->vgapal[svga->dac_write].r & 0x3f], video_6to8[svga->vgapal[svga->dac_write].g & 0x3f], video_6to8[svga->vgapal[svga->dac_write].b & 0x3f]); - svga->dac_pos = 0; - svga->dac_write = (svga->dac_write + 1) & 255; - break; - } - break; - case 0x3ce: - svga->gdcaddr = val; - break; - case 0x3cf: - o = svga->gdcreg[svga->gdcaddr & 15]; - switch (svga->gdcaddr & 15) { - case 2: - svga->colourcompare=val; - break; - case 4: - svga->readplane = val & 3; - break; - case 5: - svga->writemode = val & 3; - svga->readmode = val & 8; - svga->chain2_read = val & 0x10; - break; - case 6: - if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { - switch (val&0xC) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - } - break; - case 7: - svga->colournocare=val; - break; - } - svga->gdcreg[svga->gdcaddr & 15] = val; - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - !svga->gdcreg[1]) && svga->chain4; - if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || - ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) - svga_recalctimings(svga); - break; - } -} - - -uint8_t -svga_in(uint16_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - uint8_t ret = 0xff; - - switch (addr) { - case 0x3c0: - ret = svga->attraddr | svga->attr_palette_enable; - break; - case 0x3c1: - ret = svga->attrregs[svga->attraddr]; - break; - case 0x3c2: - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x4e) - ret = 0; - else - ret = 0x10; - break; - case 0x3c4: - ret = svga->seqaddr; - break; - case 0x3c5: - ret = svga->seqregs[svga->seqaddr & 0x0f]; - break; - case 0x3c6: - ret = svga->dac_mask; - break; - case 0x3c7: - ret = svga->dac_status; - break; - case 0x3c8: - ret = svga->dac_write; - break; - case 0x3c9: - svga->dac_status = 3; - switch (svga->dac_pos) { - case 0: - svga->dac_pos++; - if (svga->ramdac_type == RAMDAC_8BIT) - ret = svga->vgapal[svga->dac_read].r; - else - ret = svga->vgapal[svga->dac_read].r & 0x3f; - break; - case 1: - svga->dac_pos++; - if (svga->ramdac_type == RAMDAC_8BIT) - ret = svga->vgapal[svga->dac_read].g; - else - ret = svga->vgapal[svga->dac_read].g & 0x3f; - break; - case 2: - svga->dac_pos=0; - svga->dac_read = (svga->dac_read + 1) & 255; - if (svga->ramdac_type == RAMDAC_8BIT) - ret = svga->vgapal[(svga->dac_read - 1) & 255].b; - else - ret = svga->vgapal[(svga->dac_read - 1) & 255].b & 0x3f; - break; - } - break; - case 0x3cc: - ret = svga->miscout; - break; - case 0x3ce: - ret = svga->gdcaddr; - break; - case 0x3cf: - /* The spec says GDC addresses 0xF8 to 0xFB return the latch. */ - switch(svga->gdcaddr) { - case 0xf8: - ret = (svga->latch & 0xFF); - break; - case 0xf9: - ret = ((svga->latch & 0xFF00) >> 8); - break; - case 0xfa: - ret = ((svga->latch & 0xFF0000) >> 16); - break; - case 0xfb: - ret = ((svga->latch & 0xFF000000) >> 24); - break; - default: - ret = svga->gdcreg[svga->gdcaddr & 0xf]; - break; - } - break; - case 0x3da: - svga->attrff = 0; - svga->attrff = 0; - - if (svga->cgastat & 0x01) - svga->cgastat &= ~0x30; - else - svga->cgastat ^= 0x30; - ret = svga->cgastat; - break; - } - - return(ret); -} - - -void -svga_set_ramdac_type(svga_t *svga, int type) -{ - int c; - - if (svga->ramdac_type != type) { - svga->ramdac_type = type; - - for (c = 0; c < 256; c++) { - if (svga->ramdac_type == RAMDAC_8BIT) - svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); - else - svga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, - (svga->vgapal[c].g & 0x3f) * 4, - (svga->vgapal[c].b & 0x3f) * 4); - } - } -} - - -void -svga_recalctimings(svga_t *svga) -{ - double crtcconst, _dispontime, _dispofftime, disptime; - - svga->vtotal = svga->crtc[6]; - svga->dispend = svga->crtc[0x12]; - svga->vsyncstart = svga->crtc[0x10]; - svga->split = svga->crtc[0x18]; - svga->vblankstart = svga->crtc[0x15]; - - if (svga->crtc[7] & 1) - svga->vtotal |= 0x100; - if (svga->crtc[7] & 32) - svga->vtotal |= 0x200; - svga->vtotal += 2; - - if (svga->crtc[7] & 2) - svga->dispend |= 0x100; - if (svga->crtc[7] & 64) - svga->dispend |= 0x200; - svga->dispend++; - - if (svga->crtc[7] & 4) - svga->vsyncstart |= 0x100; - if (svga->crtc[7] & 128) - svga->vsyncstart |= 0x200; - svga->vsyncstart++; - - if (svga->crtc[7] & 0x10) - svga->split|=0x100; - if (svga->crtc[9] & 0x40) - svga->split|=0x200; - svga->split++; - - if (svga->crtc[7] & 0x08) - svga->vblankstart |= 0x100; - if (svga->crtc[9] & 0x20) - svga->vblankstart |= 0x200; - svga->vblankstart++; - - svga->hdisp = svga->crtc[1]; - svga->hdisp++; - - svga->htotal = svga->crtc[0]; - svga->htotal += 6; /*+6 is required for Tyrian*/ - - svga->rowoffset = svga->crtc[0x13]; - - svga->clock = (svga->vidclock) ? VGACONST2 : VGACONST1; - - svga->lowres = svga->attrregs[0x10] & 0x40; - - svga->interlace = 0; - - svga->ma_latch = (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - - svga->hdisp_time = svga->hdisp; - svga->render = svga_render_blank; - if (!svga->scrblank && svga->attr_palette_enable) { - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) /*40 column*/ { - svga->render = svga_render_text_40; - svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; - } else { - svga->render = svga_render_text_80; - svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; - } - svga->hdisp_old = svga->hdisp; - } else { - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; - svga->hdisp_old = svga->hdisp; - - switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else - svga->render = svga_render_4bpp_highres; - break; - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: case 0x60: /*256+ colours*/ - switch (svga->bpp) { - case 8: - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - break; - case 15: - if (svga->lowres) - svga->render = svga_render_15bpp_lowres; - else - svga->render = svga_render_15bpp_highres; - break; - case 16: - if (svga->lowres) - svga->render = svga_render_16bpp_lowres; - else - svga->render = svga_render_16bpp_highres; - break; - case 24: - if (svga->lowres) - svga->render = svga_render_24bpp_lowres; - else - svga->render = svga_render_24bpp_highres; - break; - case 32: - if (svga->lowres) - svga->render = svga_render_32bpp_lowres; - else - svga->render = svga_render_32bpp_highres; - break; - } - break; - } - } - } - - svga->linedbl = svga->crtc[9] & 0x80; - svga->rowcount = svga->crtc[9] & 31; - if (enable_overscan) { - overscan_y = (svga->rowcount + 1) << 1; - if (svga->seqregs[1] & 8) /*Low res (320)*/ - overscan_y <<= 1; - if (overscan_y < 16) - overscan_y = 16; - } - if (svga->recalctimings_ex) - svga->recalctimings_ex(svga); - - if (svga->vblankstart < svga->dispend) - svga->dispend = svga->vblankstart; - - crtcconst = (svga->seqregs[1] & 1) ? (svga->clock * 8.0) : (svga->clock * 9.0); - - disptime = svga->htotal; - _dispontime = svga->hdisp_time; - - if (svga->seqregs[1] & 8) { - disptime *= 2; - _dispontime *= 2; - } - _dispofftime = disptime - _dispontime; - _dispontime *= crtcconst; - _dispofftime *= crtcconst; - - svga->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - svga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); -} - - -void -svga_poll(void *p) -{ - svga_t *svga = (svga_t *)p; - uint32_t x; - int wx, wy; - - if (!svga->linepos) { - if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { - svga->hwcursor_on = 64 - svga->hwcursor_latch.yoff; - svga->hwcursor_oddeven = 0; - } - - if (svga->displine == (svga->hwcursor_latch.y + 1) && svga->hwcursor_latch.ena && - svga->interlace) { - svga->hwcursor_on = 64 - (svga->hwcursor_latch.yoff + 1); - svga->hwcursor_oddeven = 1; - } - - if (svga->displine == svga->overlay_latch.y && svga->overlay_latch.ena) { - svga->overlay_on = svga->overlay_latch.ysize - svga->overlay_latch.yoff; - svga->overlay_oddeven = 0; - } - - if (svga->displine == svga->overlay_latch.y+1 && svga->overlay_latch.ena && svga->interlace) { - svga->overlay_on = svga->overlay_latch.ysize - svga->overlay_latch.yoff; - svga->overlay_oddeven = 1; - } - - svga->vidtime += svga->dispofftime; - svga->cgastat |= 1; - svga->linepos = 1; - - if (svga->dispon) { - svga->hdisp_on=1; - - svga->ma &= svga->vram_display_mask; - if (svga->firstline == 2000) { - svga->firstline = svga->displine; - video_wait_for_buffer(); - } - - if (svga->hwcursor_on || svga->overlay_on) { - svga->changedvram[svga->ma >> 12] = svga->changedvram[(svga->ma >> 12) + 1] = - svga->interlace ? 3 : 2; - } - - if (!svga->override) - svga->render(svga); - - if (svga->overlay_on) { - if (!svga->override) - svga->overlay_draw(svga, svga->displine); - svga->overlay_on--; - if (svga->overlay_on && svga->interlace) - svga->overlay_on--; - } - - if (svga->hwcursor_on) { - if (!svga->override) - svga->hwcursor_draw(svga, svga->displine); - svga->hwcursor_on--; - if (svga->hwcursor_on && svga->interlace) - svga->hwcursor_on--; - } - - if (svga->lastline < svga->displine) - svga->lastline = svga->displine; - } - - svga->displine++; - if (svga->interlace) - svga->displine++; - if ((svga->cgastat & 8) && ((svga->displine & 15) == (svga->crtc[0x11] & 15)) && svga->vslines) - svga->cgastat &= ~8; - svga->vslines++; - if (svga->displine > 1500) - svga->displine = 0; - } else { - svga->vidtime += svga->dispontime; - - if (svga->dispon) - svga->cgastat &= ~1; - svga->hdisp_on = 0; - - svga->linepos = 0; - if (svga->sc == (svga->crtc[11] & 31)) - svga->con = 0; - if (svga->dispon) { - if (svga->linedbl && !svga->linecountff) { - svga->linecountff = 1; - svga->ma = svga->maback; - } else if (svga->sc == svga->rowcount) { - svga->linecountff = 0; - svga->sc = 0; - - svga->maback += (svga->rowoffset << 3); - if (svga->interlace) - svga->maback += (svga->rowoffset << 3); - svga->maback &= svga->vram_display_mask; - svga->ma = svga->maback; - } else { - svga->linecountff = 0; - svga->sc++; - svga->sc &= 31; - svga->ma = svga->maback; - } - } - svga->vc++; - svga->vc &= 2047; - - if (svga->vc == svga->split) { - svga->ma = svga->maback = 0; - if (svga->attrregs[0x10] & 0x20) - svga->scrollcache = 0; - } - if (svga->vc == svga->dispend) { - if (svga->vblank_start) - svga->vblank_start(svga); - svga->dispon=0; - if (svga->crtc[10] & 0x20) - svga->cursoron = 0; - else - svga->cursoron = svga->blink & 16; - - if (!(svga->gdcreg[6] & 1) && !(svga->blink & 15)) - svga->fullchange = 2; - svga->blink++; - - for (x = 0; x < ((svga->vram_mask + 1) >> 12); x++) { - if (svga->changedvram[x]) - svga->changedvram[x]--; - } - if (svga->fullchange) - svga->fullchange--; - } - if (svga->vc == svga->vsyncstart) { - svga->dispon = 0; - svga->cgastat |= 8; - x = svga->hdisp; - - if (svga->interlace && !svga->oddeven) - svga->lastline++; - if (svga->interlace && svga->oddeven) - svga->firstline--; - - wx = x; - wy = svga->lastline - svga->firstline; - - if (!svga->override) - svga_doblit(svga->firstline_draw, svga->lastline_draw + 1, wx, wy, svga); - - svga->firstline = 2000; - svga->lastline = 0; - - svga->firstline_draw = 2000; - svga->lastline_draw = 0; - - svga->oddeven ^= 1; - - changeframecount = svga->interlace ? 3 : 2; - svga->vslines = 0; - - if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1); - else - svga->ma = svga->maback = svga->ma_latch; - svga->ca = (svga->crtc[0xe] << 8) | svga->crtc[0xf]; - - svga->ma <<= 2; - svga->maback <<= 2; - svga->ca <<= 2; - - svga->video_res_x = wx; - svga->video_res_y = wy + 1; - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - svga->video_res_x /= (svga->seqregs[1] & 1) ? 8 : 9; - svga->video_res_y /= (svga->crtc[9] & 31) + 1; - svga->video_bpp = 0; - } else { - if (svga->crtc[9] & 0x80) - svga->video_res_y /= 2; - if (!(svga->crtc[0x17] & 2)) - svga->video_res_y *= 4; - else if (!(svga->crtc[0x17] & 1)) - svga->video_res_y *= 2; - svga->video_res_y /= (svga->crtc[9] & 31) + 1; - if (svga->lowres) - svga->video_res_x /= 2; - - svga->video_bpp = svga->bpp; - } - } - if (svga->vc == svga->vtotal) { - svga->vc = 0; - svga->sc = svga->crtc[8] & 0x1f; - svga->dispon = 1; - svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; - svga->scrollcache = svga->attrregs[0x13] & 7; - svga->linecountff = 0; - - svga->hwcursor_on = 0; - svga->hwcursor_latch = svga->hwcursor; - - svga->overlay_on = 0; - svga->overlay_latch = svga->overlay; - } - if (svga->sc == (svga->crtc[10] & 31)) - svga->con = 1; - } -} - - -int -svga_init(svga_t *svga, void *p, int memsize, - void (*recalctimings_ex)(struct svga_t *svga), - uint8_t (*video_in) (uint16_t addr, void *p), - void (*video_out)(uint16_t addr, uint8_t val, void *p), - void (*hwcursor_draw)(struct svga_t *svga, int displine), - void (*overlay_draw)(struct svga_t *svga, int displine)) -{ - int c, d, e; - - svga->p = p; - - for (c = 0; c < 256; c++) { - e = c; - for (d = 0; d < 8; d++) { - svga_rotate[d][c] = e; - e = (e >> 1) | ((e & 1) ? 0x80 : 0); - } - } - svga->readmode = 0; - - svga->attrregs[0x11] = 0; - svga->overscan_color = 0x000000; - - overscan_x = 16; - overscan_y = 32; - - svga->crtc[0] = 63; - svga->crtc[6] = 255; - svga->dispontime = svga->dispofftime = 1000 * (1 << TIMER_SHIFT); - svga->bpp = 8; - svga->vram = malloc(memsize); - svga->vram_max = memsize; - svga->vram_display_mask = svga->vram_mask = memsize - 1; - svga->decode_mask = 0x7fffff; - svga->changedvram = malloc(memsize >> 12); - svga->recalctimings_ex = recalctimings_ex; - svga->video_in = video_in; - svga->video_out = video_out; - svga->hwcursor_draw = hwcursor_draw; - svga->overlay_draw = overlay_draw; - - mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, - svga_read, svga_readw, svga_readl, - svga_write, svga_writew, svga_writel, - NULL, MEM_MAPPING_EXTERNAL, svga); - - timer_add(svga_poll, &svga->vidtime, TIMER_ALWAYS_ENABLED, svga); - - svga_pri = svga; - - svga->ramdac_type = RAMDAC_6BIT; - - return 0; -} - - -void -svga_close(svga_t *svga) -{ - free(svga->changedvram); - free(svga->vram); - - svga_pri = NULL; -} - - -void -svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) -{ - svga_t *svga = (svga_t *)p; - - int func_select, writemask2 = svga->writemask; - uint32_t write_mask, bit_mask, set_mask, val32 = (uint32_t) val; - - egawrites++; - - cycles -= video_timing_write_b; - - if (!linear) { - addr &= svga->banked_mask; - addr += svga->write_bank; - } - - if (!(svga->gdcreg[6] & 1)) - svga->fullchange = 2; - - if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) { - writemask2 = 1 << (addr & 3); - addr &= ~3; - } else if (svga->chain2_write) { - writemask2 &= ~0xa; - if (addr & 1) - writemask2 <<= 1; - addr &= ~1; - addr <<= 2; - } else - addr <<= 2; - addr &= svga->decode_mask; - - if (addr >= svga->vram_max) - return; - - addr &= svga->vram_mask; - - svga->changedvram[addr >> 12] = changeframecount; - - /* standard VGA latched access */ - func_select = (svga->gdcreg[3] >> 3) & 3; - - switch (svga->writemode) { - case 0: - /* rotate */ - if (svga->gdcreg[3] & 7) - val32 = svga_rotate[svga->gdcreg[3] & 7][val32]; - - /* apply set/reset mask */ - bit_mask = svga->gdcreg[8]; - - val32 |= (val32 << 8); - val32 |= (val32 << 16); - - if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - (!svga->gdcreg[1] || svga->set_reset_disabled)) { - /* mask data according to sr[2] */ - write_mask = mask16[writemask2 & 0x0f]; - addr >>= 2; - ((uint32_t *)(svga->vram))[addr] &= ~write_mask; - ((uint32_t *)(svga->vram))[addr] |= (val32 & write_mask); - return; - } - - set_mask = mask16[svga->gdcreg[1] & 0x0f]; - val32 = (val32 & ~set_mask) | (mask16[svga->gdcreg[0] & 0x0f] & set_mask); - break; - case 1: - val32 = svga->latch; - - /* mask data according to sr[2] */ - write_mask = mask16[writemask2 & 0x0f]; - addr >>= 2; - ((uint32_t *)(svga->vram))[addr] &= ~write_mask; - ((uint32_t *)(svga->vram))[addr] |= (val32 & write_mask); - return; - case 2: - val32 = mask16[val32 & 0x0f]; - bit_mask = svga->gdcreg[8]; - - if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) - func_select = 0; - break; - case 3: - /* rotate */ - if (svga->gdcreg[3] & 7) - val32 = svga_rotate[svga->gdcreg[3] & 7][val]; - - bit_mask = svga->gdcreg[8] & val32; - val32 = mask16[svga->gdcreg[0] & 0x0f]; - break; - default: - if (svga->ven_write) - svga->ven_write(svga, val, addr); - return; - } - - /* apply bit mask */ - bit_mask |= bit_mask << 8; - bit_mask |= bit_mask << 16; - - /* apply logical operation */ - switch(func_select) { - case 0: - default: - /* set */ - val32 &= bit_mask; - val32 |= (svga->latch & ~bit_mask); - break; - case 1: - /* and */ - val32 |= ~bit_mask; - val32 &= svga->latch; - break; - case 2: - /* or */ - val32 &= bit_mask; - val32 |= svga->latch; - break; - case 3: - /* xor */ - val32 &= bit_mask; - val32 ^= svga->latch; - break; - } - - /* mask data according to sr[2] */ - write_mask = mask16[writemask2 & 0x0f]; - addr >>= 2; - ((uint32_t *)(svga->vram))[addr] = (((uint32_t *)(svga->vram))[addr] & ~write_mask) | (val32 & write_mask); -} - - -uint8_t -svga_read_common(uint32_t addr, uint8_t linear, void *p) -{ - svga_t *svga = (svga_t *)p; - uint32_t latch_addr, ret; - int readplane = svga->readplane; - uint8_t ret8; - - cycles -= video_timing_read_b; - - egareads++; - - if (!linear) { - addr &= svga->banked_mask; - addr += svga->read_bank; - - latch_addr = (addr << 2) & svga->decode_mask; - } - - if (svga->chain4 || svga->fb_only) { - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; - return svga->vram[addr & svga->vram_mask]; - } else if (svga->chain2_read) { - readplane = (readplane & 2) | (addr & 1); - addr &= ~1; - addr <<= 2; - } else - addr <<= 2; - - addr &= svga->decode_mask; - - /* standard VGA latched access */ - if (linear) { - if (addr >= svga->vram_max) - return 0xff; - - addr &= svga->vram_mask; - - svga->latch = ((uint32_t *)(svga->vram))[addr >> 2]; - } else { - if (latch_addr > svga->vram_max) - svga->latch = 0xffffffff; - else { - latch_addr &= svga->vram_mask; - svga->latch = ((uint32_t *)(svga->vram))[latch_addr >> 2]; - } - - if (addr >= svga->vram_max) - return 0xff; - - addr &= svga->vram_mask; - } - - if (!(svga->gdcreg[5] & 8)) { - /* read mode 0 */ - return svga->vram[addr | readplane]; - } else { - /* read mode 1 */ - ret = (svga->latch ^ mask16[svga->colourcompare & 0x0f]) & mask16[svga->colournocare & 0x0f]; - ret8 = (ret & 0xff); - ret8 |= ((ret >> 24) & 0xff); - ret8 |= ((ret >> 16) & 0xff); - ret8 |= ((ret >> 8) & 0xff); - return(~ret8); - } -} - - -void -svga_write(uint32_t addr, uint8_t val, void *p) -{ - svga_write_common(addr, val, 0, p); -} - - -void -svga_write_linear(uint32_t addr, uint8_t val, void *p) -{ - svga_write_common(addr, val, 1, p); -} - - -uint8_t -svga_read(uint32_t addr, void *p) -{ - return svga_read_common(addr, 0, p); -} - - -uint8_t -svga_read_linear(uint32_t addr, void *p) -{ - return svga_read_common(addr, 1, p); -} - - -void -svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) -{ - int y_add = (enable_overscan) ? overscan_y : 0; - int x_add = (enable_overscan) ? 16 : 0; - uint32_t *p; - int i, j; - - svga->frames++; - - if ((xsize > 2032) || (ysize > 2032)) { - x_add = 0; - y_add = 0; - suppress_overscan = 1; - } else - suppress_overscan = 0; - - if (y1 > y2) { - video_blit_memtoscreen(32, 0, 0, 0, xsize + x_add, ysize + y_add); - return; - } - - if ((wx != xsize) || ((wy + 1) != ysize) || video_force_resize_get()) { - /* Screen res has changed.. fix up, and let them know. */ - xsize = wx; - ysize = wy + 1; - if (xsize < 64) - xsize = 640; - if (ysize < 32) - ysize = 200; - - set_screen_size(xsize+x_add,ysize+y_add); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - - if (enable_overscan && !suppress_overscan) { - if ((wx >= 160) && ((wy + 1) >= 120)) { - /* Draw (overscan_size - scroll size) lines of overscan on top. */ - for (i = 0; i < (y_add >> 1); i++) { - p = &((uint32_t *)buffer32->line[i & 0x7ff])[32]; - - for (j = 0; j < (xsize + x_add); j++) - p[j] = svga_color_transform(svga->overscan_color); - } - - /* Draw (overscan_size + scroll size) lines of overscan on the bottom. */ - for (i = 0; i < (y_add >> 1); i++) { - p = &((uint32_t *)buffer32->line[(ysize + (y_add >> 1) + i) & 0x7ff])[32]; - - for (j = 0; j < (xsize + x_add); j++) - p[j] = svga_color_transform(svga->overscan_color); - } - - for (i = (y_add >> 1); i < (ysize + (y_add >> 1)); i ++) { - p = &((uint32_t *)buffer32->line[i & 0x7ff])[32]; - - for (j = 0; j < 8; j++) { - p[j] = svga->pallook[svga->overscan_color]; - p[xsize + (x_add >> 1) + j] = svga_color_transform(svga->overscan_color); - } - } - } - } - - video_blit_memtoscreen(32, 0, y1, y2 + y_add, xsize + x_add, ysize + y_add); -} - - -void -svga_writeb_linear(uint32_t addr, uint8_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - - if (!svga->fast) { - svga_write_linear(addr, val, p); - return; - } - - egawrites++; - - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; - *(uint8_t *)&svga->vram[addr] = val; -} - - -void -svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *p) -{ - svga_t *svga = (svga_t *)p; - - if (!svga->fast) { - svga_write_common(addr, val, linear, p); - svga_write_common(addr + 1, val >> 8, linear, p); - return; - } - - egawrites += 2; - - cycles -= video_timing_write_w; - - if (!linear) - addr = (addr & svga->banked_mask) + svga->write_bank; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; - *(uint16_t *)&svga->vram[addr] = val; -} - - -void -svga_writew(uint32_t addr, uint16_t val, void *p) -{ - svga_writew_common(addr, val, 0, p); -} - - -void -svga_writew_linear(uint32_t addr, uint16_t val, void *p) -{ - svga_writew_common(addr, val, 1, p); -} - - -void -svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *p) -{ - svga_t *svga = (svga_t *)p; - - if (!svga->fast) { - svga_write(addr, val, p); - svga_write(addr + 1, val >> 8, p); - svga_write(addr + 2, val >> 16, p); - svga_write(addr + 3, val >> 24, p); - return; - } - - egawrites += 4; - - cycles -= video_timing_write_l; - - if (!linear) - addr = (addr & svga->banked_mask) + svga->write_bank; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - - svga->changedvram[addr >> 12] = changeframecount; - *(uint32_t *)&svga->vram[addr] = val; -} - - -void -svga_writel(uint32_t addr, uint32_t val, void *p) -{ - svga_writel_common(addr, val, 0, p); -} - - -void -svga_writel_linear(uint32_t addr, uint32_t val, void *p) -{ - svga_writel_common(addr, val, 1, p); -} - - -uint8_t -svga_readb_linear(uint32_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - - if (!svga->fast) - return svga_read_linear(addr, p); - - egareads++; - - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; - - return *(uint8_t *)&svga->vram[addr & svga->vram_mask]; -} - - -uint16_t -svga_readw_common(uint32_t addr, uint8_t linear, void *p) -{ - svga_t *svga = (svga_t *)p; - - if (!svga->fast) - return svga_read_common(addr, linear, p) | (svga_read_common(addr + 1, linear, p) << 8); - - egareads += 2; - - cycles -= video_timing_read_w; - - if (!linear) - addr = (addr & svga->banked_mask) + svga->read_bank; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xffff; - - return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; -} - - -uint16_t -svga_readw(uint32_t addr, void *p) -{ - return svga_readw_common(addr, 0, p); -} - - -uint16_t -svga_readw_linear(uint32_t addr, void *p) -{ - return svga_readw_common(addr, 1, p); -} - - -uint32_t -svga_readl_common(uint32_t addr, uint8_t linear, void *p) -{ - svga_t *svga = (svga_t *)p; - - if (!svga->fast) { - return svga_read_common(addr, linear, p) | (svga_read_common(addr + 1, linear, p) << 8) | - (svga_read_common(addr + 2, linear, p) << 16) | (svga_read_common(addr + 3, linear, p) << 24); - } - - egareads += 4; - - cycles -= video_timing_read_l; - - if (!linear) - addr = (addr & svga->banked_mask) + svga->read_bank; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xffffffff; - - return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; -} - - -uint32_t -svga_readl(uint32_t addr, void *p) -{ - return svga_readl_common(addr, 0, p); -} - - -uint32_t -svga_readl_linear(uint32_t addr, void *p) -{ - return svga_readl_common(addr, 1, p); -} - - -void -svga_add_status_info(char *s, int max_len, void *p) -{ - svga_t *svga = (svga_t *)p; - char temps[128]; - - if (svga->chain4) - strcpy(temps, "SVGA chained (possibly mode 13h)\n"); - else - strcpy(temps, "SVGA unchained (possibly mode-X)\n"); - strncat(s, temps, max_len); - - if (!svga->video_bpp) - strcpy(temps, "SVGA in text mode\n"); - else - sprintf(temps, "SVGA colour depth : %i bpp\n", svga->video_bpp); - strncat(s, temps, max_len); - - sprintf(temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y); - strncat(s, temps, max_len); - - sprintf(temps, "SVGA refresh rate : %i Hz\n\n", svga->frames); - svga->frames = 0; - strncat(s, temps, max_len); -} diff --git a/backup code/video - Cópia/vid_svga.h b/backup code/video - Cópia/vid_svga.h deleted file mode 100644 index 1711af4cc..000000000 --- a/backup code/video - Cópia/vid_svga.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * 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. - * - * Generic SVGA handling. - * - * Version: @(#)vid_svga.h 1.0.11 2018/04/01 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -typedef struct { - int ena, - x, y, xoff, yoff, xsize, ysize, - v_acc, h_acc; - uint32_t addr, pitch; -} hwcursor_t; - -typedef struct svga_t -{ - mem_mapping_t mapping; - - int enabled; - - uint8_t crtcreg, crtc[128], - gdcaddr, gdcreg[64], - attrff, attr_palette_enable, - attraddr, attrregs[32], - seqaddr, seqregs[64], - miscout, cgastat, - plane_mask, writemask, - colourcompare, colournocare, - scrblank, egapal[16], - *vram, *changedvram; - - int vidclock, fb_only, - fast; - - /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : - 0MB-1MB - VRAM - 1MB-2MB - VRAM mirror - 2MB-4MB - open bus - 4MB-xMB - mirror of above - - For the example memory map, decode_mask would be 4MB-1 (4MB address space), vram_max would be 2MB - (present video memory only responds to first 2MB), vram_mask would be 1MB-1 (video memory wraps at 1MB) - */ - uint32_t decode_mask; - uint32_t vram_max; - uint32_t vram_mask; - - uint8_t dac_mask, dac_status; - int dac_read, dac_write, - dac_pos, ramdac_type, - dac_r, dac_g; - - int readmode, writemode, - readplane, extvram, - chain4, chain2_write, chain2_read, - oddeven_page, oddeven_chain, - set_reset_disabled; - - uint32_t charseta, charsetb, - latch, ma_latch, - ma, maback, - write_bank, read_bank, - banked_mask, - ca, overscan_color, - pallook[256]; - - PALETTE vgapal; - - int vtotal, dispend, vsyncstart, split, vblankstart, - hdisp, hdisp_old, htotal, hdisp_time, rowoffset, - lowres, interlace, linedbl, rowcount, bpp, - dispon, hdisp_on, - vc, sc, linepos, vslines, linecountff, oddeven, - con, cursoron, blink, scrollcache, - firstline, lastline, firstline_draw, lastline_draw, - displine, fullchange, - video_res_x, video_res_y, video_bpp, frames, fps, - vram_display_mask, - hwcursor_on, overlay_on, - hwcursor_oddeven, overlay_oddeven; - - double clock; - - int64_t dispontime, dispofftime, - vidtime; - - hwcursor_t hwcursor, hwcursor_latch, - overlay, overlay_latch; - - void (*render)(struct svga_t *svga); - void (*recalctimings_ex)(struct svga_t *svga); - - void (*video_out)(uint16_t addr, uint8_t val, void *p); - uint8_t (*video_in) (uint16_t addr, void *p); - - void (*hwcursor_draw)(struct svga_t *svga, int displine); - - void (*overlay_draw)(struct svga_t *svga, int displine); - - void (*vblank_start)(struct svga_t *svga); - - void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr); - - /*If set then another device is driving the monitor output and the SVGA - card should not attempt to display anything */ - int override; - void *p; -} svga_t; - - -extern int svga_init(svga_t *svga, void *p, int memsize, - void (*recalctimings_ex)(struct svga_t *svga), - uint8_t (*video_in) (uint16_t addr, void *p), - void (*video_out)(uint16_t addr, uint8_t val, void *p), - void (*hwcursor_draw)(struct svga_t *svga, int displine), - void (*overlay_draw)(struct svga_t *svga, int displine)); -extern void svga_recalctimings(svga_t *svga); -extern void svga_close(svga_t *svga); - -uint8_t svga_read(uint32_t addr, void *p); -uint16_t svga_readw(uint32_t addr, void *p); -uint32_t svga_readl(uint32_t addr, void *p); -void svga_write(uint32_t addr, uint8_t val, void *p); -void svga_writew(uint32_t addr, uint16_t val, void *p); -void svga_writel(uint32_t addr, uint32_t val, void *p); -uint8_t svga_read_linear(uint32_t addr, void *p); -uint8_t svga_readb_linear(uint32_t addr, void *p); -uint16_t svga_readw_linear(uint32_t addr, void *p); -uint32_t svga_readl_linear(uint32_t addr, void *p); -void svga_write_linear(uint32_t addr, uint8_t val, void *p); -void svga_writeb_linear(uint32_t addr, uint8_t val, void *p); -void svga_writew_linear(uint32_t addr, uint16_t val, void *p); -void svga_writel_linear(uint32_t addr, uint32_t val, void *p); - -void svga_add_status_info(char *s, int max_len, void *p); - -extern uint8_t svga_rotate[8][256]; - -void svga_out(uint16_t addr, uint8_t val, void *p); -uint8_t svga_in(uint16_t addr, void *p); - -svga_t *svga_get_pri(); -void svga_set_override(svga_t *svga, int val); - -void svga_set_ven_write(svga_t *svga, - void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr)); - -void svga_set_ramdac_type(svga_t *svga, int type); -void svga_close(svga_t *svga); - -uint32_t svga_mask_addr(uint32_t addr, svga_t *svga); -uint32_t svga_mask_changedaddr(uint32_t addr, svga_t *svga); - -void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga); - - -enum { - RAMDAC_6BIT = 0, - RAMDAC_8BIT -}; - -extern uint32_t shade[5][256]; - - -static __inline__ uint32_t -svga_color_transform(uint32_t color) -{ - uint8_t *clr8 = (uint8_t *) &color; - if (!video_grayscale && !invert_display) - return color; - if (video_grayscale) { - if (video_graytype) { - if (video_graytype == 1) - color = ((54 * (uint32_t)clr8[2]) + (183 * (uint32_t)clr8[1]) + (18 * (uint32_t)clr8[0])) / 255; - else - color = ((uint32_t)clr8[2] + (uint32_t)clr8[1] + (uint32_t)clr8[0]) / 3; - } else - color = ((76 * (uint32_t)clr8[2]) + (150 * (uint32_t)clr8[1]) + (29 * (uint32_t)clr8[0])) / 255; - switch (video_grayscale) { - case 2: case 3: case 4: - color = shade[video_grayscale][color]; - break; - default: - clr8[3] = 0; - clr8[0] = color; - clr8[1] = clr8[2] = clr8[0]; - break; - } - } - if (invert_display) - color ^= 0x00ffffff; - return color; -} diff --git a/backup code/video - Cópia/vid_svga_render.c b/backup code/video - Cópia/vid_svga_render.c deleted file mode 100644 index 1a6912782..000000000 --- a/backup code/video - Cópia/vid_svga_render.c +++ /dev/null @@ -1,934 +0,0 @@ -/* - * 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. - * - * SVGA renderers. - * - * Version: @(#)vid_svga_render.c 1.0.10 2018/03/19 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_svga_render.h" - - -int invert_display = 0; -int video_grayscale = 0; -int video_graytype = 0; - - -uint32_t shade[5][256] = -{ - {0}, // RGB Color (unused) - {0}, // RGB Grayscale (unused) - { // Amber monitor - 0x000000, 0x060000, 0x090000, 0x0d0000, 0x100000, 0x120100, 0x150100, 0x170100, 0x1a0100, 0x1c0100, 0x1e0200, 0x210200, 0x230200, 0x250300, 0x270300, 0x290300, - 0x2b0400, 0x2d0400, 0x2f0400, 0x300500, 0x320500, 0x340500, 0x360600, 0x380600, 0x390700, 0x3b0700, 0x3d0700, 0x3f0800, 0x400800, 0x420900, 0x440900, 0x450a00, - 0x470a00, 0x480b00, 0x4a0b00, 0x4c0c00, 0x4d0c00, 0x4f0d00, 0x500d00, 0x520e00, 0x530e00, 0x550f00, 0x560f00, 0x581000, 0x591000, 0x5b1100, 0x5c1200, 0x5e1200, - 0x5f1300, 0x601300, 0x621400, 0x631500, 0x651500, 0x661600, 0x671600, 0x691700, 0x6a1800, 0x6c1800, 0x6d1900, 0x6e1a00, 0x701a00, 0x711b00, 0x721c00, 0x741c00, - 0x751d00, 0x761e00, 0x781e00, 0x791f00, 0x7a2000, 0x7c2000, 0x7d2100, 0x7e2200, 0x7f2300, 0x812300, 0x822400, 0x832500, 0x842600, 0x862600, 0x872700, 0x882800, - 0x8a2900, 0x8b2900, 0x8c2a00, 0x8d2b00, 0x8e2c00, 0x902c00, 0x912d00, 0x922e00, 0x932f00, 0x953000, 0x963000, 0x973100, 0x983200, 0x993300, 0x9b3400, 0x9c3400, - 0x9d3500, 0x9e3600, 0x9f3700, 0xa03800, 0xa23900, 0xa33a00, 0xa43a00, 0xa53b00, 0xa63c00, 0xa73d00, 0xa93e00, 0xaa3f00, 0xab4000, 0xac4000, 0xad4100, 0xae4200, - 0xaf4300, 0xb14400, 0xb24500, 0xb34600, 0xb44700, 0xb54800, 0xb64900, 0xb74a00, 0xb94a00, 0xba4b00, 0xbb4c00, 0xbc4d00, 0xbd4e00, 0xbe4f00, 0xbf5000, 0xc05100, - 0xc15200, 0xc25300, 0xc45400, 0xc55500, 0xc65600, 0xc75700, 0xc85800, 0xc95900, 0xca5a00, 0xcb5b00, 0xcc5c00, 0xcd5d00, 0xce5e00, 0xcf5f00, 0xd06000, 0xd26101, - 0xd36201, 0xd46301, 0xd56401, 0xd66501, 0xd76601, 0xd86701, 0xd96801, 0xda6901, 0xdb6a01, 0xdc6b01, 0xdd6c01, 0xde6d01, 0xdf6e01, 0xe06f01, 0xe17001, 0xe27201, - 0xe37301, 0xe47401, 0xe57501, 0xe67602, 0xe77702, 0xe87802, 0xe97902, 0xeb7a02, 0xec7b02, 0xed7c02, 0xee7e02, 0xef7f02, 0xf08002, 0xf18103, 0xf28203, 0xf38303, - 0xf48403, 0xf58503, 0xf68703, 0xf78803, 0xf88903, 0xf98a04, 0xfa8b04, 0xfb8c04, 0xfc8d04, 0xfd8f04, 0xfe9005, 0xff9105, 0xff9205, 0xff9305, 0xff9405, 0xff9606, - 0xff9706, 0xff9806, 0xff9906, 0xff9a07, 0xff9b07, 0xff9d07, 0xff9e08, 0xff9f08, 0xffa008, 0xffa109, 0xffa309, 0xffa409, 0xffa50a, 0xffa60a, 0xffa80a, 0xffa90b, - 0xffaa0b, 0xffab0c, 0xffac0c, 0xffae0d, 0xffaf0d, 0xffb00e, 0xffb10e, 0xffb30f, 0xffb40f, 0xffb510, 0xffb610, 0xffb811, 0xffb912, 0xffba12, 0xffbb13, 0xffbd14, - 0xffbe14, 0xffbf15, 0xffc016, 0xffc217, 0xffc317, 0xffc418, 0xffc619, 0xffc71a, 0xffc81b, 0xffca1c, 0xffcb1d, 0xffcc1e, 0xffcd1f, 0xffcf20, 0xffd021, 0xffd122, - 0xffd323, 0xffd424, 0xffd526, 0xffd727, 0xffd828, 0xffd92a, 0xffdb2b, 0xffdc2c, 0xffdd2e, 0xffdf2f, 0xffe031, 0xffe133, 0xffe334, 0xffe436, 0xffe538, 0xffe739 - }, - { // Green monitor - 0x000000, 0x000400, 0x000700, 0x000900, 0x000b00, 0x000d00, 0x000f00, 0x001100, 0x001300, 0x001500, 0x001600, 0x001800, 0x001a00, 0x001b00, 0x001d00, 0x001e00, - 0x002000, 0x002100, 0x002300, 0x002400, 0x002601, 0x002701, 0x002901, 0x002a01, 0x002b01, 0x002d01, 0x002e01, 0x002f01, 0x003101, 0x003201, 0x003301, 0x003401, - 0x003601, 0x003702, 0x003802, 0x003902, 0x003b02, 0x003c02, 0x003d02, 0x003e02, 0x004002, 0x004102, 0x004203, 0x004303, 0x004403, 0x004503, 0x004703, 0x004803, - 0x004903, 0x004a03, 0x004b04, 0x004c04, 0x004d04, 0x004e04, 0x005004, 0x005104, 0x005205, 0x005305, 0x005405, 0x005505, 0x005605, 0x005705, 0x005806, 0x005906, - 0x005a06, 0x005b06, 0x005d06, 0x005e07, 0x005f07, 0x006007, 0x006107, 0x006207, 0x006308, 0x006408, 0x006508, 0x006608, 0x006708, 0x006809, 0x006909, 0x006a09, - 0x006b09, 0x016c0a, 0x016d0a, 0x016e0a, 0x016f0a, 0x01700b, 0x01710b, 0x01720b, 0x01730b, 0x01740c, 0x01750c, 0x01760c, 0x01770c, 0x01780d, 0x01790d, 0x017a0d, - 0x017b0d, 0x017b0e, 0x017c0e, 0x017d0e, 0x017e0f, 0x017f0f, 0x01800f, 0x018110, 0x028210, 0x028310, 0x028410, 0x028511, 0x028611, 0x028711, 0x028812, 0x028912, - 0x028a12, 0x028a13, 0x028b13, 0x028c13, 0x028d14, 0x028e14, 0x038f14, 0x039015, 0x039115, 0x039215, 0x039316, 0x039416, 0x039417, 0x039517, 0x039617, 0x039718, - 0x049818, 0x049918, 0x049a19, 0x049b19, 0x049c19, 0x049c1a, 0x049d1a, 0x049e1b, 0x059f1b, 0x05a01b, 0x05a11c, 0x05a21c, 0x05a31c, 0x05a31d, 0x05a41d, 0x06a51e, - 0x06a61e, 0x06a71f, 0x06a81f, 0x06a920, 0x06aa20, 0x07aa21, 0x07ab21, 0x07ac21, 0x07ad22, 0x07ae22, 0x08af23, 0x08b023, 0x08b024, 0x08b124, 0x08b225, 0x09b325, - 0x09b426, 0x09b526, 0x09b527, 0x0ab627, 0x0ab728, 0x0ab828, 0x0ab929, 0x0bba29, 0x0bba2a, 0x0bbb2a, 0x0bbc2b, 0x0cbd2b, 0x0cbe2c, 0x0cbf2c, 0x0dbf2d, 0x0dc02d, - 0x0dc12e, 0x0ec22e, 0x0ec32f, 0x0ec42f, 0x0fc430, 0x0fc530, 0x0fc631, 0x10c731, 0x10c832, 0x10c932, 0x11c933, 0x11ca33, 0x11cb34, 0x12cc35, 0x12cd35, 0x12cd36, - 0x13ce36, 0x13cf37, 0x13d037, 0x14d138, 0x14d139, 0x14d239, 0x15d33a, 0x15d43a, 0x16d43b, 0x16d53b, 0x17d63c, 0x17d73d, 0x17d83d, 0x18d83e, 0x18d93e, 0x19da3f, - 0x19db40, 0x1adc40, 0x1adc41, 0x1bdd41, 0x1bde42, 0x1cdf43, 0x1ce043, 0x1de044, 0x1ee145, 0x1ee245, 0x1fe346, 0x1fe446, 0x20e447, 0x20e548, 0x21e648, 0x22e749, - 0x22e74a, 0x23e84a, 0x23e94b, 0x24ea4c, 0x25ea4c, 0x25eb4d, 0x26ec4e, 0x27ed4e, 0x27ee4f, 0x28ee50, 0x29ef50, 0x29f051, 0x2af152, 0x2bf153, 0x2cf253, 0x2cf354, - 0x2df455, 0x2ef455, 0x2ff556, 0x2ff657, 0x30f758, 0x31f758, 0x32f859, 0x32f95a, 0x33fa5a, 0x34fa5b, 0x35fb5c, 0x36fc5d, 0x37fd5d, 0x38fd5e, 0x38fe5f, 0x39ff60 - }, - { // White monitor - 0x000000, 0x010102, 0x020203, 0x020304, 0x030406, 0x040507, 0x050608, 0x060709, 0x07080a, 0x08090c, 0x080a0d, 0x090b0e, 0x0a0c0f, 0x0b0d10, 0x0c0e11, 0x0d0f12, - 0x0e1013, 0x0f1115, 0x101216, 0x111317, 0x121418, 0x121519, 0x13161a, 0x14171b, 0x15181c, 0x16191d, 0x171a1e, 0x181b1f, 0x191c20, 0x1a1d21, 0x1b1e22, 0x1c1f23, - 0x1d2024, 0x1e2125, 0x1f2226, 0x202327, 0x212428, 0x222529, 0x22262b, 0x23272c, 0x24282d, 0x25292e, 0x262a2f, 0x272b30, 0x282c30, 0x292d31, 0x2a2e32, 0x2b2f33, - 0x2c3034, 0x2d3035, 0x2e3136, 0x2f3237, 0x303338, 0x313439, 0x32353a, 0x33363b, 0x34373c, 0x35383d, 0x36393e, 0x373a3f, 0x383b40, 0x393c41, 0x3a3d42, 0x3b3e43, - 0x3c3f44, 0x3d4045, 0x3e4146, 0x3f4247, 0x404348, 0x414449, 0x42454a, 0x43464b, 0x44474c, 0x45484d, 0x46494d, 0x474a4e, 0x484b4f, 0x484c50, 0x494d51, 0x4a4e52, - 0x4b4f53, 0x4c5054, 0x4d5155, 0x4e5256, 0x4f5357, 0x505458, 0x515559, 0x52565a, 0x53575b, 0x54585b, 0x55595c, 0x565a5d, 0x575b5e, 0x585c5f, 0x595d60, 0x5a5e61, - 0x5b5f62, 0x5c6063, 0x5d6164, 0x5e6265, 0x5f6366, 0x606466, 0x616567, 0x626668, 0x636769, 0x64686a, 0x65696b, 0x666a6c, 0x676b6d, 0x686c6e, 0x696d6f, 0x6a6e70, - 0x6b6f70, 0x6c7071, 0x6d7172, 0x6f7273, 0x707374, 0x707475, 0x717576, 0x727677, 0x747778, 0x757879, 0x767979, 0x777a7a, 0x787b7b, 0x797c7c, 0x7a7d7d, 0x7b7e7e, - 0x7c7f7f, 0x7d8080, 0x7e8181, 0x7f8281, 0x808382, 0x818483, 0x828584, 0x838685, 0x848786, 0x858887, 0x868988, 0x878a89, 0x888b89, 0x898c8a, 0x8a8d8b, 0x8b8e8c, - 0x8c8f8d, 0x8d8f8e, 0x8e908f, 0x8f9190, 0x909290, 0x919391, 0x929492, 0x939593, 0x949694, 0x959795, 0x969896, 0x979997, 0x989a98, 0x999b98, 0x9a9c99, 0x9b9d9a, - 0x9c9e9b, 0x9d9f9c, 0x9ea09d, 0x9fa19e, 0xa0a29f, 0xa1a39f, 0xa2a4a0, 0xa3a5a1, 0xa4a6a2, 0xa6a7a3, 0xa7a8a4, 0xa8a9a5, 0xa9aaa5, 0xaaaba6, 0xabaca7, 0xacada8, - 0xadaea9, 0xaeafaa, 0xafb0ab, 0xb0b1ac, 0xb1b2ac, 0xb2b3ad, 0xb3b4ae, 0xb4b5af, 0xb5b6b0, 0xb6b7b1, 0xb7b8b2, 0xb8b9b2, 0xb9bab3, 0xbabbb4, 0xbbbcb5, 0xbcbdb6, - 0xbdbeb7, 0xbebfb8, 0xbfc0b8, 0xc0c1b9, 0xc1c2ba, 0xc2c3bb, 0xc3c4bc, 0xc5c5bd, 0xc6c6be, 0xc7c7be, 0xc8c8bf, 0xc9c9c0, 0xcacac1, 0xcbcbc2, 0xccccc3, 0xcdcdc3, - 0xcecec4, 0xcfcfc5, 0xd0d0c6, 0xd1d1c7, 0xd2d2c8, 0xd3d3c9, 0xd4d4c9, 0xd5d5ca, 0xd6d6cb, 0xd7d7cc, 0xd8d8cd, 0xd9d9ce, 0xdadacf, 0xdbdbcf, 0xdcdcd0, 0xdeddd1, - 0xdfded2, 0xe0dfd3, 0xe1e0d4, 0xe2e1d4, 0xe3e2d5, 0xe4e3d6, 0xe5e4d7, 0xe6e5d8, 0xe7e6d9, 0xe8e7d9, 0xe9e8da, 0xeae9db, 0xebeadc, 0xecebdd, 0xedecde, 0xeeeddf, - 0xefeedf, 0xf0efe0, 0xf1f0e1, 0xf2f1e2, 0xf3f2e3, 0xf4f3e3, 0xf6f3e4, 0xf7f4e5, 0xf8f5e6, 0xf9f6e7, 0xfaf7e8, 0xfbf8e9, 0xfcf9e9, 0xfdfaea, 0xfefbeb, 0xfffcec - } -}; - -void svga_render_blank(svga_t *svga) -{ - int x, xx; - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x < svga->hdisp; x++) - { - switch (svga->seqregs[1] & 9) - { - case 0: - for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 9) + xx + 32 + x_add] = svga_color_transform(0); - break; - case 1: - for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 8) + xx + 32 + x_add] = svga_color_transform(0); - break; - case 8: - for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 18) + xx + 32 + x_add] = svga_color_transform(0); - break; - case 9: - for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 16) + xx + 32 + x_add] = svga_color_transform(0); - break; - } - } -} - -void svga_render_text_40(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (svga->fullchange) - { - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add]; - int x, xx; - int drawcursor; - uint8_t chr, attr, dat; - uint32_t charaddr; - int fg, bg; - int xinc = (svga->seqregs[1] & 1) ? 16 : 18; - - for (x = 0; x < svga->hdisp; x += xinc) - { - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; - if (attr & 8) charaddr = svga->charsetb + (chr * 128); - else charaddr = svga->charseta + (chr * 128); - - if (drawcursor) - { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } - else - { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) - { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } - - fg = svga_color_transform(fg); - bg = svga_color_transform(bg); - - dat = svga->vram[charaddr + (svga->sc << 2)]; - if (svga->seqregs[1] & 1) - { - for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; - } - else - { - for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[16] = p[17] = bg; - else - p[16] = p[17] = (dat & 1) ? fg : bg; - } - svga->ma += 4; - p += xinc; - } - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_text_80(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (svga->fullchange) - { - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add]; - int x, xx; - int drawcursor; - uint8_t chr, attr, dat; - uint32_t charaddr; - int fg, bg; - int xinc = (svga->seqregs[1] & 1) ? 8 : 9; - - for (x = 0; x < svga->hdisp; x += xinc) - { - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; - - - if (attr & 8) charaddr = svga->charsetb + (chr * 128); - else charaddr = svga->charseta + (chr * 128); - - if (drawcursor) - { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } - else - { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) - { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } - - fg = svga_color_transform(fg); - bg = svga_color_transform(bg); - - dat = svga->vram[charaddr + (svga->sc << 2)]; - if (svga->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; - } - svga->ma += 4; - p += xinc; - } - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_text_80_ksc5601(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (svga->fullchange) - { - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add]; - int x, xx; - int drawcursor; - uint8_t chr, attr, dat, nextchr; - uint32_t charaddr; - int fg, bg; - int xinc = (svga->seqregs[1] & 1) ? 8 : 9; - - for (x = 0; x < svga->hdisp; x += xinc) - { - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; - - - if (drawcursor) - { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } - else - { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) - { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } - - fg = svga_color_transform(fg); - bg = svga_color_transform(bg); - - if(x + xinc < svga->hdisp && (chr & nextchr & 0x80)) - { - if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) - dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc]; - else - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc]; - } - else - { - if (attr & 8) charaddr = svga->charsetb + (chr * 128); - else charaddr = svga->charseta + (chr * 128); - - dat = svga->vram[charaddr + (svga->sc << 2)]; - } - if (svga->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; - } - svga->ma += 4; - p += xinc; - - if(x + xinc < svga->hdisp && (chr & nextchr & 0x80)) - { - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; - - if (drawcursor) - { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } - else - { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) - { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } - - if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) - dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc + 16]; - else - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16]; - if (svga->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; - } - - svga->ma += 4; - p += xinc; - x += xinc; - } - } - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_2bpp_lowres(svga_t *svga) -{ - int changed_offset; - - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) - { - int x; - int offset = ((8 - svga->scrollcache) << 1) + 16; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 16) - { - uint8_t dat[2]; - - dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]; - dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1]; - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - - p[0] = p[1] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]); - p[2] = p[3] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]); - p[4] = p[5] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]); - p[6] = p[7] = svga_color_transform(svga->pallook[svga->egapal[dat[0] & 3]]); - p[8] = p[9] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]); - p[10] = p[11] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]); - p[12] = p[13] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]); - p[14] = p[15] = svga_color_transform(svga->pallook[svga->egapal[dat[1] & 3]]); - - p += 16; - } - } -} - -void svga_render_2bpp_highres(svga_t *svga) -{ - int changed_offset; - - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) - { - int x; - int offset = (8 - svga->scrollcache) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 8) - { - uint8_t dat[2]; - - dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]; - dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1]; - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - - p[0] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]); - p[1] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]); - p[2] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]); - p[3] = svga_color_transform(svga->pallook[svga->egapal[dat[0] & 3]]); - p[4] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]); - p[5] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]); - p[6] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]); - p[7] = svga_color_transform(svga->pallook[svga->egapal[dat[1] & 3]]); - - p += 8; - } - } -} - -void svga_render_4bpp_lowres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = ((8 - svga->scrollcache) << 1) + 16; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 16) - { - uint8_t edat[4]; - uint8_t dat; - - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]); - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[2] = p[3] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[6] = p[7] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[10] = p[11] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[14] = p[15] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - - p += 16; - } - } -} - -void svga_render_4bpp_highres(svga_t *svga) -{ - int changed_offset; - - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) - { - int x; - int offset = (8 - svga->scrollcache) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 8) - { - uint8_t edat[4]; - uint8_t dat; - - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma | ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]); - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[1] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[3] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[5] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[7] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - - p += 8; - } - } -} - -void svga_render_8bpp_lowres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 8) - { - uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - - p[0] = p[1] = svga_color_transform(svga->pallook[dat & 0xff]); - p[2] = p[3] = svga_color_transform(svga->pallook[(dat >> 8) & 0xff]); - p[4] = p[5] = svga_color_transform(svga->pallook[(dat >> 16) & 0xff]); - p[6] = p[7] = svga_color_transform(svga->pallook[(dat >> 24) & 0xff]); - - svga->ma += 4; - p += 8; - } - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_8bpp_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 8) - { - uint32_t dat; - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = svga_color_transform(svga->pallook[dat & 0xff]); - p[1] = svga_color_transform(svga->pallook[(dat >> 8) & 0xff]); - p[2] = svga_color_transform(svga->pallook[(dat >> 16) & 0xff]); - p[3] = svga_color_transform(svga->pallook[(dat >> 24) & 0xff]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - p[4] = svga_color_transform(svga->pallook[dat & 0xff]); - p[5] = svga_color_transform(svga->pallook[(dat >> 8) & 0xff]); - p[6] = svga_color_transform(svga->pallook[(dat >> 16) & 0xff]); - p[7] = svga_color_transform(svga->pallook[(dat >> 24) & 0xff]); - - svga->ma += 8; - p += 8; - } - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_15bpp_lowres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 4) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - - p[x] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - - p[x] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_15bpp_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 8) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 3] = svga_color_transform(video_15to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 5] = svga_color_transform(video_15to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 7] = svga_color_transform(video_15to32[dat >> 16]); - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_16bpp_lowres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 4) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - - p[x] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - - p[x] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_16bpp_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 8) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 3] = svga_color_transform(video_16to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 5] = svga_color_transform(video_16to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 7] = svga_color_transform(video_16to32[dat >> 16]); - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_24bpp_lowres(svga_t *svga) -{ - int x, offset; - uint32_t fg; - - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - offset = (8 - (svga->scrollcache & 6)) + 24; - - for (x = 0; x <= svga->hdisp; x++) - { - fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - svga->ma += 3; - svga->ma &= svga->vram_display_mask; - ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = svga_color_transform(fg); - } - } -} - -void svga_render_24bpp_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 4) - { - uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[x] = svga_color_transform(dat & 0xffffff); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); - p[x + 1] = svga_color_transform(dat & 0xffffff); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); - p[x + 2] = svga_color_transform(dat & 0xffffff); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); - p[x + 3] = svga_color_transform(dat & 0xffffff); - - svga->ma += 12; - } - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_32bpp_lowres(svga_t *svga) -{ - int x, offset; - uint32_t fg; - - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - offset = (8 - (svga->scrollcache & 6)) + 24; - - for (x = 0; x <= svga->hdisp; x++) - { - fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = svga_color_transform(fg); - } - } -} - -/*72% - 91%*/ -void svga_render_32bpp_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x++) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = svga_color_transform(dat & 0xffffff); - } - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_ABGR8888_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x++) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = svga_color_transform((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); - } - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_RGBA8888_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x++) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = svga_color_transform(dat >> 8); - } - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - } -} diff --git a/backup code/video - Cópia/vid_svga_render.h b/backup code/video - Cópia/vid_svga_render.h deleted file mode 100644 index 4bbc43272..000000000 --- a/backup code/video - Cópia/vid_svga_render.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - * - * SVGA renderers. - * - * Version: @(#)vid_svga_render.h 1.0.1 2018/03/12 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -extern int firstline_draw, lastline_draw; -extern int displine; -extern int sc; - -extern uint32_t ma, ca; -extern int con, cursoron, cgablink; - -extern int scrollcache; - -extern uint8_t edatlookup[4][4]; - -void svga_render_blank(svga_t *svga); -void svga_render_text_40(svga_t *svga); -void svga_render_text_80(svga_t *svga); -void svga_render_text_80_ksc5601(svga_t *svga); - -void svga_render_2bpp_lowres(svga_t *svga); -void svga_render_2bpp_highres(svga_t *svga); -void svga_render_4bpp_lowres(svga_t *svga); -void svga_render_4bpp_highres(svga_t *svga); -void svga_render_8bpp_lowres(svga_t *svga); -void svga_render_8bpp_highres(svga_t *svga); -void svga_render_15bpp_lowres(svga_t *svga); -void svga_render_15bpp_highres(svga_t *svga); -void svga_render_16bpp_lowres(svga_t *svga); -void svga_render_16bpp_highres(svga_t *svga); -void svga_render_24bpp_lowres(svga_t *svga); -void svga_render_24bpp_highres(svga_t *svga); -void svga_render_32bpp_lowres(svga_t *svga); -void svga_render_32bpp_highres(svga_t *svga); -void svga_render_ABGR8888_lowres(svga_t *svga); -void svga_render_ABGR8888_highres(svga_t *svga); -void svga_render_RGBA8888_lowres(svga_t *svga); -void svga_render_RGBA8888_highres(svga_t *svga); - -extern void (*svga_render)(svga_t *svga); diff --git a/backup code/video - Cópia/vid_table.c b/backup code/video - Cópia/vid_table.c deleted file mode 100644 index a6d153367..000000000 --- a/backup code/video - Cópia/vid_table.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * 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. - * - * Define all known video cards. - * - * Version: @(#)vid_table.c 1.0.29 2018/05/10 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../machine/machine.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" -#include "../plat.h" -#include "video.h" -#include "vid_svga.h" - -#include "vid_ati18800.h" -#include "vid_ati28800.h" -#include "vid_ati_mach64.h" -#include "vid_cga.h" -#include "vid_cl54xx.h" -#include "vid_compaq_cga.h" -#include "vid_ega.h" -#include "vid_et4000.h" -#include "vid_et4000w32.h" -#include "vid_genius.h" -#include "vid_hercules.h" -#include "vid_herculesplus.h" -#include "vid_incolor.h" -#include "vid_colorplus.h" -#include "vid_mda.h" -#ifdef DEV_BRANCH -# ifdef USE_RIVA -# include "vid_nvidia.h" -# endif -#endif -#include "vid_oak_oti.h" -#include "vid_paradise.h" -#include "vid_s3.h" -#include "vid_s3_virge.h" -#include "vid_tgui9440.h" -#include "vid_ti_cf62011.h" -#include "vid_tvga.h" -#include "vid_vga.h" -#include "vid_voodoo.h" -#include "vid_wy700.h" - - -enum { - VIDEO_ISA = 0, - VIDEO_BUS -}; - -#define VIDEO_FLAG_TYPE_CGA 0 -#define VIDEO_FLAG_TYPE_MDA 1 -#define VIDEO_FLAG_TYPE_SPECIAL 2 -#define VIDEO_FLAG_TYPE_MASK 3 - -typedef struct { - const char *name; - const char *internal_name; - const device_t *device; - int legacy_id; - int flags; - video_timings_t timing; -} VIDEO_CARD; - - -static const VIDEO_CARD -video_cards[] = { - { "None", "none", NULL, GFX_NONE }, - { "Internal", "internal", NULL, GFX_INTERNAL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_isa", &mach64gx_isa_device, GFX_MACH64GX_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, - { "[ISA] ATI Korean VGA (ATI-28800-5)", "ati28800k", &ati28800k_device, GFX_ATIKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, - { "[ISA] ATI VGA-88 (ATI-18800-1)", "ati18800v", &ati18800_vga88_device, GFX_VGA88, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] ATI VGA Charger (ATI-28800-5)", "ati28800", &ati28800_device, GFX_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, - { "[ISA] ATI VGA Edge-16 (ATI-18800-5)", "ati18800", &ati18800_device, GFX_VGAEDGE16, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) - { "[ISA] ATI VGA Wonder (ATI-18800)", "ati18800w", &ati18800_wonder_device, GFX_VGAWONDER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, -#endif -#if defined(DEV_BRANCH) && defined(USE_XL24) - { "[ISA] ATI VGA Wonder XL24 (ATI-28800-6)", "ati28800w", &ati28800_wonderxl24_device, GFX_VGAWONDERXL24, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, -#endif - { "[ISA] CGA", "cga", &cga_device, GFX_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] Chips & Technologies SuperEGA", "superega", &sega_device, GFX_SUPER_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] Cirrus Logic CL-GD 5428", "cl_gd5428_isa", &gd5428_isa_device, GFX_CL_GD5428_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, - { "[ISA] Cirrus Logic CL-GD 5429", "cl_gd5429_isa", &gd5429_isa_device, GFX_CL_GD5429_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, - { "[ISA] Cirrus Logic CL-GD 5434", "cl_gd5434_isa", &gd5434_isa_device, GFX_CL_GD5434_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, - { "[ISA] Compaq ATI VGA Wonder XL (ATI-28800-5)", "compaq_ati28800", &compaq_ati28800_device, GFX_VGAWONDERXL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, - { "[ISA] Compaq CGA", "compaq_cga", &compaq_cga_device, GFX_COMPAQ_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] Compaq CGA 2", "compaq_cga_2", &compaq_cga_2_device, GFX_COMPAQ_CGA_2, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] Compaq EGA", "compaq_ega", &cpqega_device, GFX_COMPAQ_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] EGA", "ega", &ega_device, GFX_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] Hercules", "hercules", &hercules_device, GFX_HERCULES, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] Hercules Plus", "hercules_plus", &herculesplus_device, GFX_HERCULESPLUS, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] MDA", "mda", &mda_device, GFX_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] MDSI Genius", "genius", &genius_device, GFX_GENIUS, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] OAK OTI-037C", "oti037c", &oti037c_device, GFX_OTI037C, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, - { "[ISA] OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, - { "[ISA] OAK OTI-077", "oti077", &oti077_device, GFX_OTI077, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, - { "[ISA] Paradise PVGA1A", "pvga1a", ¶dise_pvga1a_device, GFX_PVGA1A, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] Paradise WD90C11-LR", "wd90c11", ¶dise_wd90c11_device, GFX_WD90C11, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - { "[ISA] Paradise WD90C30-LR", "wd90c30", ¶dise_wd90c30_device, GFX_WD90C30, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, - { "[ISA] Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, -#if defined(DEV_BRANCH) && defined(USE_TI) - { "[ISA] TI CF62011 SVGA", "ti_cf62011", &ti_cf62011_device, GFX_TICF62011, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, -#endif - {"[ISA] Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, - {"[ISA] Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, - {"[ISA] VGA", "vga", &vga_device, GFX_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] Wyse 700", "wy700", &wy700_device, GFX_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[PCI] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_pci", &mach64gx_pci_device, GFX_MACH64GX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, - {"[PCI] ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, - {"[PCI] Cardex Tseng ET4000/w32p", "et4000w32p_pci", &et4000w32p_cardex_pci_device, GFX_ET4000W32_CARDEX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, - {"[PCI] Cirrus Logic CL-GD 5430", "cl_gd5430_pci", &gd5430_pci_device, GFX_CL_GD5430_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[PCI] Cirrus Logic CL-GD 5434", "cl_gd5434_pci", &gd5434_pci_device, GFX_CL_GD5434_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[PCI] Cirrus Logic CL-GD 5436", "cl_gd5436_pci", &gd5436_pci_device, GFX_CL_GD5436_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[PCI] Cirrus Logic CL-GD 5440", "cl_gd5440_pci", &gd5440_pci_device, GFX_CL_GD5440_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[PCI] Cirrus Logic CL-GD 5446", "cl_gd5446_pci", &gd5446_pci_device, GFX_CL_GD5446_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[PCI] Cirrus Logic CL-GD 5480", "cl_gd5480_pci", &gd5480_pci_device, GFX_CL_GD5480_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) - {"[PCI] Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32_pci", &et4000w32p_pci_device, GFX_ET4000W32_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, -#endif - {"[PCI] Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000_pci", &s3_virge_pci_device, GFX_VIRGE_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"[PCI] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_pci", &s3_virge_988_pci_device, GFX_VIRGEVX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, - {"[PCI] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_pci", &s3_diamond_stealth64_pci_device, GFX_STEALTH64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, -#if defined(DEV_BRANCH) && defined(USE_RIVA) - {"[PCI] nVidia RIVA 128", "riva128", &riva128_device, GFX_RIVA128, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}}, - /*{"[PCI] nVidia RIVA TNT", "rivatnt", &rivatnt_device, GFX_RIVATNT, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}}, - {"[PCI] nVidia RIVA TNT2", "rivatnt2", &rivatnt2_device, GFX_RIVATNT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}},*/ -#endif - {"[PCI] Number Nine 9FX (S3 Trio64)", "n9_9fx_pci", &s3_9fx_pci_device, GFX_N9_9FX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"[PCI] Paradise Bahamas 64 (S3 Vision864)", "bahamas64_pci", &s3_bahamas64_pci_device, GFX_BAHAMAS64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, - {"[PCI] Phoenix S3 Vision864", "px_vision864_pci", &s3_phoenix_vision864_pci_device, GFX_PHOENIX_VISION864_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, - {"[PCI] Phoenix S3 Trio32", "px_trio32_pci", &s3_phoenix_trio32_pci_device, GFX_PHOENIX_TRIO32_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"[PCI] Phoenix S3 Trio64", "px_trio64_pci", &s3_phoenix_trio64_pci_device, GFX_PHOENIX_TRIO64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"[PCI] S3 ViRGE/DX", "virge375_pci", &s3_virge_375_pci_device, GFX_VIRGEDX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"[PCI] S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20_pci", &s3_virge_375_4_pci_device, GFX_VIRGEDX4_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"[PCI] STB Nitro 64V (CL-GD 5446)", "cl_gd5446_stb_pci", &gd5446_stb_pci_device, GFX_CL_GD5446_STB_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[PCI] Trident TGUI9440", "tgui9440_pci", &tgui9440_pci_device, GFX_TGUI9440_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, - {"[VLB] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_vlb", &mach64gx_vlb_device, GFX_MACH64GX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, - {"[VLB] Cardex Tseng ET4000/w32p", "et4000w32p_vlb", &et4000w32p_cardex_vlb_device, GFX_ET4000W32_CARDEX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, - {"[VLB] Cirrus Logic CL-GD 5428", "cl_gd5428_vlb", &gd5428_vlb_device, GFX_CL_GD5428_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[VLB] Cirrus Logic CL-GD 5429", "cl_gd5429_vlb", &gd5429_vlb_device, GFX_CL_GD5429_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[VLB] Cirrus Logic CL-GD 5434", "cl_gd5434_vlb", &gd5434_vlb_device, GFX_CL_GD5434_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) - {"[VLB] Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32_vlb", &et4000w32p_vlb_device, GFX_ET4000W32_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, -#endif - {"[VLB] Diamond SpeedStar PRO (CL-GD 5426)", "cl_gd5426_vlb", &gd5426_vlb_device, GFX_CL_GD5426_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[VLB] Diamond SpeedStar PRO SE (CL-GD 5430)", "cl_gd5430_vlb", &gd5430_vlb_device, GFX_CL_GD5430_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[VLB] Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000_vlb", &s3_virge_vlb_device, GFX_VIRGE_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"[VLB] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_vlb", &s3_virge_988_vlb_device, GFX_VIRGEVX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, - {"[VLB] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_vlb", &s3_diamond_stealth64_vlb_device, GFX_STEALTH64_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, - {"[VLB] Number Nine 9FX (S3 Trio64)", "n9_9fx_vlb", &s3_9fx_vlb_device, GFX_N9_9FX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"[VLB] Paradise Bahamas 64 (S3 Vision864)", "bahamas64_vlb", &s3_bahamas64_vlb_device, GFX_BAHAMAS64_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, - {"[VLB] Phoenix S3 Vision864", "px_vision864_vlb", &s3_phoenix_vision864_vlb_device, GFX_PHOENIX_VISION864_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, - {"[VLB] Phoenix S3 Trio32", "px_trio32_vlb", &s3_phoenix_trio32_vlb_device, GFX_PHOENIX_TRIO32_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"[VLB] Phoenix S3 Trio64", "px_trio64_vlb", &s3_phoenix_trio64_vlb_device, GFX_PHOENIX_TRIO64_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"[VLB] S3 ViRGE/DX", "virge375_vlb", &s3_virge_375_vlb_device, GFX_VIRGEDX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"[VLB] S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20_vlb", &s3_virge_375_4_vlb_device, GFX_VIRGEDX4_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"[VLB] Trident TGUI9400CXi", "tgui9400cxi_vlb", &tgui9400cxi_device, GFX_TGUI9400CXI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, - {"[VLB] Trident TGUI9440", "tgui9440_vlb", &tgui9440_vlb_device, GFX_TGUI9440_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, - {"", "", NULL, -1 } -}; - - -#ifdef ENABLE_VID_TABLE_LOG -int vid_table_do_log = ENABLE_VID_TABLE_LOG; -#endif - - -static void -vid_table_log(const char *fmt, ...) -{ -#ifdef ENABLE_VID_TABLE_LOG - va_list ap; - - if (vid_table_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -void -video_reset(int card) -{ - vid_table_log("VIDEO: reset (romset=%d, gfxcard=%d, internal=%d)\n", - romset, card, (machines[machine].flags & MACHINE_VIDEO)?1:0); - - /* Reset the CGA palette. */ - cga_palette = 0; - cgapal_rebuild(); - - if (fontdatksc5601) { - free(fontdatksc5601); - fontdatksc5601 = NULL; - } - - /* Do not initialize internal cards here. */ - if (!(card == GFX_NONE) && \ - !(card == GFX_INTERNAL) && !machines[machine].fixed_gfxcard) { - vid_table_log("VIDEO: initializing '%s'\n", video_cards[video_old_to_new(card)].name); - - /* Initialize the video card. */ - device_add(video_cards[video_old_to_new(card)].device); - } - - /* Enable the Voodoo if configured. */ - if (voodoo_enabled) - device_add(&voodoo_device); -} - - -int -video_card_available(int card) -{ - if (video_cards[card].device) - return(device_available(video_cards[card].device)); - - return(1); -} - - -char * -video_card_getname(int card) -{ - return((char *) video_cards[card].name); -} - - -const device_t * -video_card_getdevice(int card) -{ - return(video_cards[card].device); -} - - -int -video_card_has_config(int card) -{ - if (video_cards[card].device == NULL) return(0); - - return(video_cards[card].device->config ? 1 : 0); -} - - -video_timings_t * -video_card_gettiming(int card) -{ - return((void *) &video_cards[card].timing); -} - - -int -video_card_getid(char *s) -{ - int c = 0; - - while (video_cards[c].legacy_id != -1) { - if (!strcmp((char *) video_cards[c].name, s)) - return(c); - c++; - } - - return(0); -} - - -int -video_old_to_new(int card) -{ - int c = 0; - - while (video_cards[c].legacy_id != -1) { - if (video_cards[c].legacy_id == card) - return(c); - c++; - } - - return(0); -} - - -int -video_new_to_old(int card) -{ - return(video_cards[card].legacy_id); -} - - -char * -video_get_internal_name(int card) -{ - return((char *) video_cards[card].internal_name); -} - - -int -video_get_video_from_internal_name(char *s) -{ - int c = 0; - - while (video_cards[c].legacy_id != -1) { - if (!strcmp((char *) video_cards[c].internal_name, s)) - return(video_cards[c].legacy_id); - c++; - } - - return(0); -} - -int video_is_mda(void) -{ - switch (romset) - { - case ROM_IBMPCJR: - case ROM_TANDY: - case ROM_TANDY1000HX: - case ROM_TANDY1000SL2: - case ROM_PC1512: - case ROM_PC1640: - case ROM_PC200: - case ROM_OLIM24: - case ROM_PC2086: - case ROM_PC3086: - case ROM_MEGAPC: - case ROM_MEGAPCDX: - case ROM_IBMPS1_2011: - case ROM_IBMPS2_M30_286: - case ROM_IBMPS2_M50: - case ROM_IBMPS2_M55SX: - case ROM_IBMPS2_M70_TYPE3: - case ROM_IBMPS2_M70_TYPE4: - case ROM_IBMPS2_M80: - case ROM_IBMPS1_2121: - case ROM_T3100E: - return 0; - } - return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_MDA; -} - -int video_is_cga(void) -{ - switch (romset) - { - case ROM_IBMPCJR: - case ROM_TANDY: - case ROM_TANDY1000HX: - case ROM_TANDY1000SL2: - case ROM_PC1512: - case ROM_PC200: - case ROM_OLIM24: - case ROM_T3100E: - return 1; - - case ROM_PC1640: - case ROM_PC2086: - case ROM_PC3086: - case ROM_MEGAPC: - case ROM_MEGAPCDX: - case ROM_IBMPS1_2011: - case ROM_IBMPS2_M30_286: - case ROM_IBMPS2_M50: - case ROM_IBMPS2_M55SX: - case ROM_IBMPS2_M70_TYPE3: - case ROM_IBMPS2_M70_TYPE4: - case ROM_IBMPS2_M80: - case ROM_IBMPS1_2121: - return 0; - } - return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_CGA; -} - -int video_is_ega_vga(void) -{ - switch (romset) - { - case ROM_IBMPCJR: - case ROM_TANDY: - case ROM_TANDY1000HX: - case ROM_TANDY1000SL2: - case ROM_PC1512: - case ROM_PC200: - case ROM_OLIM24: - case ROM_T3100E: - return 0; - - case ROM_PC1640: - case ROM_PC2086: - case ROM_PC3086: - case ROM_MEGAPC: - case ROM_MEGAPCDX: - case ROM_IBMPS1_2011: - case ROM_IBMPS2_M30_286: - case ROM_IBMPS2_M50: - case ROM_IBMPS2_M55SX: - case ROM_IBMPS2_M70_TYPE3: - case ROM_IBMPS2_M70_TYPE4: - case ROM_IBMPS2_M80: - case ROM_IBMPS1_2121: - return 1; - } - return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_SPECIAL; -} diff --git a/backup code/video - Cópia/vid_tgui9440.c b/backup code/video - Cópia/vid_tgui9440.c deleted file mode 100644 index 7dfe400dd..000000000 --- a/backup code/video - Cópia/vid_tgui9440.c +++ /dev/null @@ -1,1796 +0,0 @@ -/* - * 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. - * - * Trident TGUI9400CXi and TGUI9440 emulation. - * - * TGUI9400CXi has extended write modes, controlled by extended - * GDC registers : - * - * GDC[0x10] - Control - * bit 0 - pixel width (1 = 16 bit, 0 = 8 bit) - * bit 1 - mono->colour expansion (1 = enabled, - * 0 = disabled) - * bit 2 - mono->colour expansion transparency - * (1 = transparent, 0 = opaque) - * bit 3 - extended latch copy - * GDC[0x11] - Background colour (low byte) - * GDC[0x12] - Background colour (high byte) - * GDC[0x14] - Foreground colour (low byte) - * GDC[0x15] - Foreground colour (high byte) - * GDC[0x17] - Write mask (low byte) - * GDC[0x18] - Write mask (high byte) - * - * Mono->colour expansion will expand written data 8:1 to 8/16 - * consecutive bytes. - * MSB is processed first. On word writes, low byte is processed - * first. 1 bits write foreground colour, 0 bits write background - * colour unless transparency is enabled. - * If the relevant bit is clear in the write mask then the data - * is not written. - * - * With 16-bit pixel width, each bit still expands to one byte, - * so the TGUI driver doubles up monochrome data. - * - * While there is room in the register map for three byte colours, - * I don't believe 24-bit colour is supported. The TGUI9440 - * blitter has the same limitation. - * - * I don't think double word writes are supported. - * - * Extended latch copy uses an internal 16 byte latch. Reads load - * the latch, writing writes out 16 bytes. I don't think the - * access size or host data has any affect, but the Windows 3.1 - * driver always reads bytes and write words of 0xffff. - * - * Version: @(#)vid_tgui9440.c 1.0.6 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "../cpu/cpu.h" -#include "../plat.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_svga_render.h" -#include "vid_tkd8001_ramdac.h" -#include "vid_tgui9440.h" - -/*TGUI9400CXi has extended write modes, controlled by extended GDC registers : - - GDC[0x10] - Control - bit 0 - pixel width (1 = 16 bit, 0 = 8 bit) - bit 1 - mono->colour expansion (1 = enabled, 0 = disabled) - bit 2 - mono->colour expansion transparency (1 = tranparent, 0 = opaque) - bit 3 - extended latch copy - GDC[0x11] - Background colour (low byte) - GDC[0x12] - Background colour (high byte) - GDC[0x14] - Foreground colour (low byte) - GDC[0x15] - Foreground colour (high byte) - GDC[0x17] - Write mask (low byte) - GDC[0x18] - Write mask (high byte) - - Mono->colour expansion will expand written data 8:1 to 8/16 consecutive bytes. - MSB is processed first. On word writes, low byte is processed first. 1 bits write - foreground colour, 0 bits write background colour unless transparency is enabled. - If the relevant bit is clear in the write mask then the data is not written. - - With 16-bit pixel width, each bit still expands to one byte, so the TGUI driver - doubles up monochrome data. - - While there is room in the register map for three byte colours, I don't believe - 24-bit colour is supported. The TGUI9440 blitter has the same limitation. - - I don't think double word writes are supported. - - Extended latch copy uses an internal 16 byte latch. Reads load the latch, writing - writes out 16 bytes. I don't think the access size or host data has any affect, - but the Windows 3.1 driver always reads bytes and write words of 0xffff.*/ - -#define EXT_CTRL_16BIT 0x01 -#define EXT_CTRL_MONO_EXPANSION 0x02 -#define EXT_CTRL_MONO_TRANSPARENT 0x04 -#define EXT_CTRL_LATCH_COPY 0x08 - -#define FIFO_SIZE 65536 -#define FIFO_MASK (FIFO_SIZE - 1) -#define FIFO_ENTRY_SIZE (1 << 31) - -#define FIFO_ENTRIES (tgui->fifo_write_idx - tgui->fifo_read_idx) -#define FIFO_FULL ((tgui->fifo_write_idx - tgui->fifo_read_idx) >= FIFO_SIZE) -#define FIFO_EMPTY (tgui->fifo_read_idx == tgui->fifo_write_idx) - -#define FIFO_TYPE 0xff000000 -#define FIFO_ADDR 0x00ffffff - -enum -{ - TGUI_9400CXI = 0, - TGUI_9440 -}; - -enum -{ - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_FB_BYTE = (0x04 << 24), - FIFO_WRITE_FB_WORD = (0x05 << 24), - FIFO_WRITE_FB_LONG = (0x06 << 24) -}; - -typedef struct -{ - uint32_t addr_type; - uint32_t val; -} fifo_entry_t; - -typedef struct tgui_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t accel_mapping; - - rom_t bios_rom; - - svga_t svga; - int pci; - - tkd8001_ramdac_t ramdac; /*TGUI9400CXi*/ - - int type; - - struct - { - uint16_t src_x, src_y; - uint16_t dst_x, dst_y; - uint16_t size_x, size_y; - uint16_t fg_col, bg_col; - uint8_t rop; - uint16_t flags; - uint8_t pattern[0x80]; - int command; - int offset; - uint8_t ger22; - - int x, y; - uint32_t src, dst, src_old, dst_old; - int pat_x, pat_y; - int use_src; - - int pitch, bpp; - - uint16_t tgui_pattern[8][8]; - } accel; - - uint8_t ext_gdc_regs[16]; /*TGUI9400CXi only*/ - uint8_t copy_latch[16]; - - uint8_t tgui_3d8, tgui_3d9; - int oldmode; - uint8_t oldctrl1; - uint8_t oldctrl2,newctrl2; - - uint32_t linear_base, linear_size; - - int ramdac_state; - uint8_t ramdac_ctrl; - - int clock_m, clock_n, clock_k; - - uint32_t vram_size, vram_mask; - - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; - - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; - - int blitter_busy; - uint64_t blitter_time; - uint64_t status_time; - - volatile int write_blitter; -} tgui_t; - -void tgui_recalcmapping(tgui_t *tgui); - -static void fifo_thread(void *param); - -uint8_t tgui_accel_read(uint32_t addr, void *priv); -uint16_t tgui_accel_read_w(uint32_t addr, void *priv); -uint32_t tgui_accel_read_l(uint32_t addr, void *priv); - -void tgui_accel_write(uint32_t addr, uint8_t val, void *priv); -void tgui_accel_write_w(uint32_t addr, uint16_t val, void *priv); -void tgui_accel_write_l(uint32_t addr, uint32_t val, void *priv); - -void tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv); -void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv); -void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv); - -static uint8_t tgui_ext_linear_read(uint32_t addr, void *p); -static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p); -static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p); -static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *p); - -static uint8_t tgui_ext_read(uint32_t addr, void *p); -static void tgui_ext_write(uint32_t addr, uint8_t val, void *p); -static void tgui_ext_writew(uint32_t addr, uint16_t val, void *p); -static void tgui_ext_writel(uint32_t addr, uint32_t val, void *p); - -void tgui_out(uint16_t addr, uint8_t val, void *p) -{ - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; - - uint8_t old; - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; - - switch (addr) - { - case 0x3C5: - switch (svga->seqaddr & 0xf) - { - case 0xB: - tgui->oldmode=1; - break; - case 0xC: - if (svga->seqregs[0xe] & 0x80) - svga->seqregs[0xc] = val; - break; - case 0xd: - if (tgui->oldmode) - tgui->oldctrl2 = val; - else - tgui->newctrl2=val; - break; - case 0xE: - if (tgui->oldmode) - tgui->oldctrl1 = val; - 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; - } - return; - } - break; - - case 0x3C6: - if (tgui->type == TGUI_9400CXI) - { - tkd8001_ramdac_out(addr, val, &tgui->ramdac, svga); - return; - } - if (tgui->ramdac_state == 4) - { - tgui->ramdac_state = 0; - tgui->ramdac_ctrl = val; - switch (tgui->ramdac_ctrl & 0xf0) - { - case 0x10: - svga->bpp = 15; - break; - case 0x30: - svga->bpp = 16; - break; - case 0xd0: - svga->bpp = 24; - break; - default: - svga->bpp = 8; - break; - } - return; - } - case 0x3C7: case 0x3C8: case 0x3C9: - if (tgui->type == TGUI_9400CXI) - { - tkd8001_ramdac_out(addr, val, &tgui->ramdac, svga); - return; - } - tgui->ramdac_state = 0; - break; - - case 0x3CF: - if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) - { - old = tgui->ext_gdc_regs[svga->gdcaddr & 15]; - tgui->ext_gdc_regs[svga->gdcaddr & 15] = val; - if (svga->gdcaddr == 16) - tgui_recalcmapping(tgui); - return; - } - switch (svga->gdcaddr & 15) - { - case 0x6: - if (svga->gdcreg[6] != val) - { - svga->gdcreg[6] = val; - tgui_recalcmapping(tgui); - } - return; - - case 0xE: - svga->gdcreg[0xe] = val ^ 2; - if ((svga->gdcreg[0xf] & 1) == 1) - svga->read_bank = (svga->gdcreg[0xe] & 0xf) * 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; - break; - } - break; - case 0x3D4: - svga->crtcreg = val & 0x7f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) - { - if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - switch (svga->crtcreg) - { - case 0x21: - if (old != val) - { - if (!tgui->pci) - { - tgui->linear_base = ((val & 0xf) | ((val >> 2) & 0x30)) << 20; - tgui->linear_size = (val & 0x10) ? 0x200000 : 0x100000; - tgui->svga.decode_mask = (val & 0x10) ? 0x1fffff : 0xfffff; - } - tgui_recalcmapping(tgui); - } - break; - - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - if (tgui->type >= TGUI_9440) - { - svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff; - svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff; - svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f; - svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f; - svga->hwcursor.addr = (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x7) << 18) | (svga->hwcursor.yoff * 8); - } - break; - - case 0x50: - if (tgui->type >= TGUI_9440) - { - svga->hwcursor.ena = val & 0x80; - svga->hwcursor.xsize = (val & 1) ? 64 : 32; - svga->hwcursor.ysize = (val & 1) ? 64 : 32; - } - break; - } - return; - case 0x3D8: - tgui->tgui_3d8 = val; - if (svga->gdcreg[0xf] & 4) - { - svga->write_bank = (val & 0x1f) * 65536; - if (!(svga->gdcreg[0xf] & 1)) - svga->read_bank = (val & 0x1f) * 65536; - } - return; - case 0x3D9: - tgui->tgui_3d9 = val; - if ((svga->gdcreg[0xf] & 5) == 5) - svga->read_bank = (val & 0x1F) * 65536; - return; - - case 0x43c8: - tgui->clock_n = val & 0x7f; - tgui->clock_m = (tgui->clock_m & ~1) | (val >> 7); - break; - case 0x43c9: - tgui->clock_m = (tgui->clock_m & ~0x1e) | ((val << 1) & 0x1e); - tgui->clock_k = (val & 0x10) >> 4; - break; - } - svga_out(addr, val, svga); -} - -uint8_t tgui_in(uint16_t addr, void *p) -{ - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; - - switch (addr) - { - case 0x3C5: - if ((svga->seqaddr & 0xf) == 0xb) - { - tgui->oldmode = 0; - switch (tgui->type) - { - case TGUI_9400CXI: - return 0x93; /*TGUI9400CXi*/ - case TGUI_9440: - return 0xe3; /*TGUI9440AGi*/ - } - } - if ((svga->seqaddr & 0xf) == 0xd) - { - if (tgui->oldmode) - return tgui->oldctrl2; - return tgui->newctrl2; - } - if ((svga->seqaddr & 0xf) == 0xe) - { - if (tgui->oldmode) - return tgui->oldctrl1; - } - break; - case 0x3C6: - if (tgui->type == TGUI_9400CXI) - return tkd8001_ramdac_in(addr, &tgui->ramdac, svga); - if (tgui->ramdac_state == 4) - return tgui->ramdac_ctrl; - tgui->ramdac_state++; - break; - case 0x3C7: case 0x3C8: case 0x3C9: - if (tgui->type == TGUI_9400CXI) - return tkd8001_ramdac_in(addr, &tgui->ramdac, svga); - tgui->ramdac_state = 0; - break; - case 0x3CF: - if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) - return tgui->ext_gdc_regs[svga->gdcaddr & 15]; - break; - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - return svga->crtc[svga->crtcreg]; - case 0x3d8: - return tgui->tgui_3d8; - case 0x3d9: - return tgui->tgui_3d9; - } - return svga_in(addr, svga); -} - -void tgui_recalctimings(svga_t *svga) -{ - tgui_t *tgui = (tgui_t *)svga->p; - - if (svga->crtc[0x29] & 0x10) - svga->rowoffset += 0x100; - - if (tgui->type >= TGUI_9440 && svga->bpp == 24) - svga->hdisp = (svga->crtc[1] + 1) * 8; - - if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000; - if ((svga->crtc[0x27] & 0x01) == 0x01) svga->ma_latch |= 0x20000; - if ((svga->crtc[0x27] & 0x02) == 0x02) svga->ma_latch |= 0x40000; - - if (tgui->oldctrl2 & 0x10) - svga->rowoffset <<= 1; - if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) - svga->ma_latch <<= 1; - - if (tgui->oldctrl2 & 0x10) /*I'm not convinced this is the right register for this function*/ - svga->lowres=0; - - svga->lowres = !(svga->crtc[0x2a] & 0x40); - - svga->interlace = svga->crtc[0x1e] & 4; - if (svga->interlace && tgui->type < TGUI_9440) - svga->rowoffset >>= 1; - - if (svga->crtc[0x17] & 4) - { - svga->vtotal *= 2; - svga->dispend *= 2; - svga->vsyncstart *= 2; - svga->split *= 2; - svga->vblankstart *= 2; - } - - if (tgui->type >= TGUI_9440) - { - if (svga->miscout & 8) - svga->clock = cpuclock / (((tgui->clock_n + 8) * 14318180.0) / ((tgui->clock_m + 2) * (1 << tgui->clock_k))); - - if (svga->gdcreg[0xf] & 0x08) - svga->clock *= 2; - else if (svga->gdcreg[0xf] & 0x40) - svga->clock *= 3; - } - else - { - switch (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8)) - { - case 0x02: svga->clock = cpuclock/ 44900000.0; break; - case 0x03: svga->clock = cpuclock/ 36000000.0; break; - case 0x04: svga->clock = cpuclock/ 57272000.0; break; - case 0x05: svga->clock = cpuclock/ 65000000.0; break; - case 0x06: svga->clock = cpuclock/ 50350000.0; break; - case 0x07: svga->clock = cpuclock/ 40000000.0; break; - case 0x08: svga->clock = cpuclock/ 88000000.0; break; - case 0x09: svga->clock = cpuclock/ 98000000.0; break; - case 0x0a: svga->clock = cpuclock/118800000.0; break; - case 0x0b: svga->clock = cpuclock/108000000.0; break; - case 0x0c: svga->clock = cpuclock/ 72000000.0; break; - case 0x0d: svga->clock = cpuclock/ 77000000.0; break; - case 0x0e: svga->clock = cpuclock/ 80000000.0; break; - case 0x0f: svga->clock = cpuclock/ 75000000.0; break; - } - if (svga->gdcreg[0xf] & 0x08) - { - svga->htotal *= 2; - svga->hdisp *= 2; - svga->hdisp_time *= 2; - } - } - - if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) - { - switch (svga->bpp) - { - case 8: - svga->render = svga_render_8bpp_highres; - break; - case 15: - svga->render = svga_render_15bpp_highres; - if (tgui->type < TGUI_9440) - svga->hdisp /= 2; - break; - case 16: - svga->render = svga_render_16bpp_highres; - if (tgui->type < TGUI_9440) - svga->hdisp /= 2; - break; - case 24: - svga->render = svga_render_24bpp_highres; - if (tgui->type < TGUI_9440) - svga->hdisp = (svga->hdisp * 2) / 3; - break; - } - } -} - -void tgui_recalcmapping(tgui_t *tgui) -{ - svga_t *svga = &tgui->svga; - - if (tgui->type == TGUI_9400CXI) - { - if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) - { - mem_mapping_set_handler(&tgui->linear_mapping, - tgui_ext_linear_read, NULL, NULL, - tgui_ext_linear_write, tgui_ext_linear_writew, tgui_ext_linear_writel); - mem_mapping_set_handler(&svga->mapping, - tgui_ext_read, NULL, NULL, - tgui_ext_write, tgui_ext_writew, tgui_ext_writel); - } - else if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_EXPANSION) - { - mem_mapping_set_handler(&tgui->linear_mapping, - svga_read_linear, svga_readw_linear, svga_readl_linear, - tgui_ext_linear_write, tgui_ext_linear_writew, tgui_ext_linear_writel); - mem_mapping_set_handler(&svga->mapping, - svga_read, svga_readw, svga_readl, - tgui_ext_write, tgui_ext_writew, tgui_ext_writel); - } - else - { - mem_mapping_set_handler(&tgui->linear_mapping, - svga_read_linear, svga_readw_linear, svga_readl_linear, - svga_write_linear, svga_writew_linear, svga_writel_linear); - mem_mapping_set_handler(&svga->mapping, - svga_read, svga_readw, svga_readl, - svga_write, svga_writew, svga_writel); - } - } - - if (svga->crtc[0x21] & 0x20) - { - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&tgui->linear_mapping, tgui->linear_base, tgui->linear_size); - if (tgui->type >= TGUI_9440) - { - mem_mapping_enable(&tgui->accel_mapping); - mem_mapping_disable(&svga->mapping); - } - else - { - switch (svga->gdcreg[6] & 0xC) - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - } - } - else - { - mem_mapping_disable(&tgui->linear_mapping); - mem_mapping_disable(&tgui->accel_mapping); - switch (svga->gdcreg[6] & 0xC) - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_enable(&tgui->accel_mapping); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - } -} - -void tgui_hwcursor_draw(svga_t *svga, int displine) -{ - uint32_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 8; - - dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; - dat[1] = (svga->vram[svga->hwcursor_latch.addr + 4] << 24) | (svga->vram[svga->hwcursor_latch.addr + 5] << 16) | (svga->vram[svga->hwcursor_latch.addr + 6] << 8) | svga->vram[svga->hwcursor_latch.addr + 7]; - for (xx = 0; xx < 32; xx++) - { - if (offset >= svga->hwcursor_latch.x) - { - if (!(dat[0] & 0x80000000)) - ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x80000000) ? 0xffffff : 0; - else if (dat[1] & 0x80000000) - ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; - } - - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - svga->hwcursor_latch.addr += 8; - - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 8; -} - -uint8_t tgui_pci_read(int func, int addr, void *p) -{ - tgui_t *tgui = (tgui_t *)p; - - switch (addr) - { - case 0x00: return 0x23; /*Trident*/ - case 0x01: return 0x10; - - case 0x02: return 0x40; /*TGUI9440 (9682)*/ - case 0x03: return 0x94; - - case 0x04: return 0x03; /*Respond to IO and memory accesses*/ - - case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ - - case 0x08: return 0; /*Revision ID*/ - case 0x09: return 0; /*Programming interface*/ - - case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/ - case 0x0b: return 0x03; - - case 0x10: return 0x00; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: return tgui->linear_base >> 16; - case 0x13: return tgui->linear_base >> 24; - - case 0x30: return 0x01; /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return 0x0C; - case 0x33: return 0x00; - } - return 0; -} - -void tgui_pci_write(int func, int addr, uint8_t val, void *p) -{ - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; - - switch (addr) - { - case 0x12: - tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xe0) << 16); - tgui->linear_size = 2 << 20; - tgui->svga.decode_mask = 0x1fffff; - svga->crtc[0x21] = (svga->crtc[0x21] & ~0xf) | (val >> 4); - tgui_recalcmapping(tgui); - break; - case 0x13: - tgui->linear_base = (tgui->linear_base & 0xe00000) | (val << 24); - tgui->linear_size = 2 << 20; - tgui->svga.decode_mask = 0x1fffff; - svga->crtc[0x21] = (svga->crtc[0x21] & ~0xc0) | (val >> 6); - tgui_recalcmapping(tgui); - break; - } -} - -static void *tgui_init(const device_t *info, wchar_t *bios_fn, int type) -{ - tgui_t *tgui = malloc(sizeof(tgui_t)); - memset(tgui, 0, sizeof(tgui_t)); - - tgui->vram_size = device_get_config_int("memory") << 20; - tgui->vram_mask = tgui->vram_size - 1; - - tgui->type = type; - - tgui->pci = !!(info->flags & DEVICE_PCI); - - rom_init(&tgui->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - svga_init(&tgui->svga, tgui, tgui->vram_size, - tgui_recalctimings, - tgui_in, tgui_out, - tgui_hwcursor_draw, - NULL); - - mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, 0, &tgui->svga); - mem_mapping_add(&tgui->accel_mapping, 0xbc000, 0x4000, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, 0, tgui); - mem_mapping_disable(&tgui->accel_mapping); - - io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - if (tgui->type >= TGUI_9440) - io_sethandler(0x43c8, 0x0002, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - - if ((info->flags & DEVICE_PCI) && (tgui->type >= TGUI_9440)) - pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui); - - tgui->wake_fifo_thread = thread_create_event(); - tgui->fifo_not_full_event = thread_create_event(); - tgui->fifo_thread = thread_create(fifo_thread, tgui); - - return tgui; -} - -static void *tgui9400cxi_init(const device_t *info) -{ - return tgui_init(info, L"roms/video/tgui9440/9400CXI.vbi", TGUI_9400CXI); -} - -static void *tgui9440_init(const device_t *info) -{ - return tgui_init(info, L"roms/video/tgui9440/9440.vbi", TGUI_9440); -} - -static int tgui9400cxi_available() -{ - return rom_present(L"roms/video/tgui9440/9400CXI.vbi"); -} - -static int tgui9440_available() -{ - return rom_present(L"roms/video/tgui9440/9440.vbi"); -} - -void tgui_close(void *p) -{ - tgui_t *tgui = (tgui_t *)p; - - svga_close(&tgui->svga); - - thread_kill(tgui->fifo_thread); - thread_destroy_event(tgui->wake_fifo_thread); - thread_destroy_event(tgui->fifo_not_full_event); - - free(tgui); -} - -void tgui_speed_changed(void *p) -{ - tgui_t *tgui = (tgui_t *)p; - - svga_recalctimings(&tgui->svga); -} - -void tgui_force_redraw(void *p) -{ - tgui_t *tgui = (tgui_t *)p; - - tgui->svga.fullchange = changeframecount; -} - - -static uint8_t tgui_ext_linear_read(uint32_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; - int c; - - cycles -= video_timing_read_b; - - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; - - addr &= ~0xf; - for (c = 0; c < 16; c++) - tgui->copy_latch[c] = svga->vram[addr+c]; - - return svga->vram[addr & svga->vram_mask]; -} - -static uint8_t tgui_ext_read(uint32_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - - addr = (addr & svga->banked_mask) + svga->read_bank; - - return tgui_ext_linear_read(addr, svga); -} - -static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; - int c; - uint8_t fg[2] = {tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5]}; - uint8_t bg[2] = {tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2]}; - uint8_t mask = tgui->ext_gdc_regs[7]; - - cycles -= video_timing_write_b; - - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - addr &= ~0x7; - svga->changedvram[addr >> 12] = changeframecount; - - switch (tgui->ext_gdc_regs[0] & 0xf) - { - /*8-bit mono->colour expansion, unmasked*/ - case 2: - for (c = 7; c >= 0; c--) - { - if (mask & (1 << c)) - *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr++; - } - break; - - /*16-bit mono->colour expansion, unmasked*/ - case 3: - for (c = 7; c >= 0; c--) - { - if (mask & (1 << c)) - *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr++; - } - break; - - /*8-bit mono->colour expansion, masked*/ - case 6: - for (c = 7; c >= 0; c--) - { - if ((val & mask) & (1 << c)) - *(uint8_t *)&svga->vram[addr] = fg[0]; - addr++; - } - break; - - /*16-bit mono->colour expansion, masked*/ - case 7: - for (c = 7; c >= 0; c--) - { - if ((val & mask) & (1 << c)) - *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; - addr++; - } - break; - - case 0x8: case 0x9: case 0xa: case 0xb: - case 0xc: case 0xd: case 0xe: case 0xf: - addr &= ~0xf; - for (c = 0; c < 16; c++) - *(uint8_t *)&svga->vram[addr+c] = tgui->copy_latch[c]; - break; - } -} - -static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; - int c; - uint8_t fg[2] = {tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5]}; - uint8_t bg[2] = {tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2]}; - uint16_t mask = (tgui->ext_gdc_regs[7] << 8) | tgui->ext_gdc_regs[8]; - - cycles -= video_timing_write_w; - - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - addr &= ~0xf; - svga->changedvram[addr >> 12] = changeframecount; - - val = (val >> 8) | (val << 8); - - switch (tgui->ext_gdc_regs[0] & 0xf) - { - /*8-bit mono->colour expansion, unmasked*/ - case 2: - for (c = 15; c >= 0; c--) - { - if (mask & (1 << c)) - *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr++; - } - break; - - /*16-bit mono->colour expansion, unmasked*/ - case 3: - for (c = 15; c >= 0; c--) - { - if (mask & (1 << c)) - *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr++; - } - break; - - /*8-bit mono->colour expansion, masked*/ - case 6: - for (c = 15; c >= 0; c--) - { - if ((val & mask) & (1 << c)) - *(uint8_t *)&svga->vram[addr] = fg[0]; - addr++; - } - break; - - /*16-bit mono->colour expansion, masked*/ - case 7: - for (c = 15; c >= 0; c--) - { - if ((val & mask) & (1 << c)) - *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; - addr++; - } - break; - - case 0x8: case 0x9: case 0xa: case 0xb: - case 0xc: case 0xd: case 0xe: case 0xf: - for (c = 0; c < 16; c++) - *(uint8_t *)&svga->vram[addr+c] = tgui->copy_latch[c]; - break; - } -} - -static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *p) -{ - tgui_ext_linear_writew(addr, val, p); -} - -static void tgui_ext_write(uint32_t addr, uint8_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - - addr = (addr & svga->banked_mask) + svga->read_bank; - - tgui_ext_linear_write(addr, val, svga); -} -static void tgui_ext_writew(uint32_t addr, uint16_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - - addr = (addr & svga->banked_mask) + svga->read_bank; - - tgui_ext_linear_writew(addr, val, svga); -} -static void tgui_ext_writel(uint32_t addr, uint32_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - - addr = (addr & svga->banked_mask) + svga->read_bank; - - tgui_ext_linear_writel(addr, val, svga); -} - - -enum -{ - TGUI_BITBLT = 1 -}; - -enum -{ - TGUI_SRCCPU = 0, - - TGUI_SRCDISP = 0x04, /*Source is from display*/ - TGUI_PATMONO = 0x20, /*Pattern is monochrome and needs expansion*/ - TGUI_SRCMONO = 0x40, /*Source is monochrome from CPU and needs expansion*/ - TGUI_TRANSENA = 0x1000, /*Transparent (no draw when source == bg col)*/ - TGUI_TRANSREV = 0x2000, /*Reverse fg/bg for transparent*/ - TGUI_SOLIDFILL = 0x4000 /*Pattern all zero?*/ -}; - -#define READ(addr, dat) if (tgui->accel.bpp == 0) dat = svga->vram[addr & 0x1fffff]; \ - else dat = vram_w[addr & 0xfffff]; - -#define MIX() do \ - { \ - out = 0; \ - for (c=0;c<16;c++) \ - { \ - d=(dst_dat & (1<accel.rop & (1<accel.bpp == 0) \ - { \ - svga->vram[addr & 0x1fffff] = dat; \ - svga->changedvram[((addr) & 0x1fffff) >> 12] = changeframecount; \ - } \ - else \ - { \ - vram_w[addr & 0xfffff] = dat; \ - svga->changedvram[((addr) & 0xfffff) >> 11] = changeframecount; \ - } - -void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) -{ - svga_t *svga = &tgui->svga; - int x, y; - int c, d; - uint16_t src_dat, dst_dat, pat_dat; - uint16_t out; - int xdir = (tgui->accel.flags & 0x200) ? -1 : 1; - int ydir = (tgui->accel.flags & 0x100) ? -1 : 1; - uint16_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col; - uint16_t *vram_w = (uint16_t *)svga->vram; - - if (tgui->accel.bpp == 0) - trans_col &= 0xff; - - if (count != -1 && !tgui->accel.x && (tgui->accel.flags & TGUI_SRCMONO)) - { - count -= tgui->accel.offset; - cpu_dat <<= tgui->accel.offset; - } - if (count == -1) - { - tgui->accel.x = tgui->accel.y = 0; - } - if (tgui->accel.flags & TGUI_SOLIDFILL) - { - for (y = 0; y < 8; y++) - { - for (x = 0; x < 8; x++) - { - tgui->accel.tgui_pattern[y][x] = tgui->accel.fg_col; - } - } - } - else if (tgui->accel.flags & TGUI_PATMONO) - { - for (y = 0; y < 8; y++) - { - for (x = 0; x < 8; x++) - { - tgui->accel.tgui_pattern[y][x] = (tgui->accel.pattern[y] & (1 << x)) ? tgui->accel.fg_col : tgui->accel.bg_col; - } - } - } - else - { - if (tgui->accel.bpp == 0) - { - for (y = 0; y < 8; y++) - { - for (x = 0; x < 8; x++) - { - tgui->accel.tgui_pattern[y][x] = tgui->accel.pattern[x + y*8]; - } - } - } - else - { - for (y = 0; y < 8; y++) - { - for (x = 0; x < 8; x++) - { - tgui->accel.tgui_pattern[y][x] = tgui->accel.pattern[x*2 + y*16] | (tgui->accel.pattern[x*2 + y*16 + 1] << 8); - } - } - } - } - switch (tgui->accel.command) - { - case TGUI_BITBLT: - if (count == -1) - { - tgui->accel.src = tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch); - tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch); - tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.pat_y = tgui->accel.dst_y; - } - - switch (tgui->accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP)) - { - case TGUI_SRCCPU: - if (count == -1) - { - if (svga->crtc[0x21] & 0x20) - { - tgui->write_blitter = 1; - } - if (tgui->accel.use_src) - return; - } - else - count >>= 3; - while (count) - { - if (tgui->accel.bpp == 0) - { - src_dat = cpu_dat >> 24; - cpu_dat <<= 8; - } - else - { - src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00); - cpu_dat <<= 16; - count--; - } - READ(tgui->accel.dst, dst_dat); - pat_dat = tgui->accel.tgui_pattern[tgui->accel.pat_y & 7][tgui->accel.pat_x & 7]; - - if (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col) - { - MIX(); - - WRITE(tgui->accel.dst, out); - } - - tgui->accel.src += xdir; - tgui->accel.dst += xdir; - tgui->accel.pat_x += xdir; - - tgui->accel.x++; - if (tgui->accel.x > tgui->accel.size_x) - { - tgui->accel.x = 0; - tgui->accel.y++; - - tgui->accel.pat_x = tgui->accel.dst_x; - - 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; - - if (tgui->accel.y > tgui->accel.size_y) - { - if (svga->crtc[0x21] & 0x20) - { - tgui->write_blitter = 0; - } - return; - } - if (tgui->accel.use_src) - return; - } - count--; - } - break; - - case TGUI_SRCMONO | TGUI_SRCCPU: - if (count == -1) - { - if (svga->crtc[0x21] & 0x20) - tgui->write_blitter = 1; - - if (tgui->accel.use_src) - return; - } - while (count) - { - src_dat = ((cpu_dat >> 31) ? tgui->accel.fg_col : tgui->accel.bg_col); - if (tgui->accel.bpp == 0) - src_dat &= 0xff; - - READ(tgui->accel.dst, dst_dat); - pat_dat = tgui->accel.tgui_pattern[tgui->accel.pat_y & 7][tgui->accel.pat_x & 7]; - - if (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col) - { - MIX(); - - WRITE(tgui->accel.dst, out); - } - cpu_dat <<= 1; - tgui->accel.src += xdir; - tgui->accel.dst += xdir; - tgui->accel.pat_x += xdir; - - tgui->accel.x++; - if (tgui->accel.x > tgui->accel.size_x) - { - tgui->accel.x = 0; - tgui->accel.y++; - - tgui->accel.pat_x = tgui->accel.dst_x; - - 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; - - if (tgui->accel.y > tgui->accel.size_y) - { - if (svga->crtc[0x21] & 0x20) - { - tgui->write_blitter = 0; - } - return; - } - if (tgui->accel.use_src) - return; - } - count--; - } - break; - - default: - while (count) - { - READ(tgui->accel.src, src_dat); - READ(tgui->accel.dst, dst_dat); - pat_dat = tgui->accel.tgui_pattern[tgui->accel.pat_y & 7][tgui->accel.pat_x & 7]; - - if (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col) - { - MIX(); - - WRITE(tgui->accel.dst, out); - } - - tgui->accel.src += xdir; - tgui->accel.dst += xdir; - tgui->accel.pat_x += xdir; - - tgui->accel.x++; - if (tgui->accel.x > tgui->accel.size_x) - { - tgui->accel.x = 0; - tgui->accel.y++; - - tgui->accel.pat_x = tgui->accel.dst_x; - - 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; - - if (tgui->accel.y > tgui->accel.size_y) - return; - } - count--; - } - break; - } - break; - } -} - -static void tgui_accel_write_fifo(tgui_t *tgui, uint32_t addr, uint8_t val) -{ - switch (addr & 0xff) - { - case 0x22: - tgui->accel.ger22 = val; - tgui->accel.pitch = 512 << ((val >> 2) & 3); - tgui->accel.bpp = (val & 3) ? 1 : 0; - tgui->accel.pitch >>= tgui->accel.bpp; - break; - - case 0x24: /*Command*/ - tgui->accel.command = val; - tgui_accel_command(-1, 0, tgui); - break; - - case 0x27: /*ROP*/ - tgui->accel.rop = val; - tgui->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33); - break; - - case 0x28: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0xff00) | val; - break; - case 0x29: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0xff) | (val << 8); - break; - - case 0x2b: - tgui->accel.offset = val & 7; - break; - - case 0x2c: /*Foreground colour*/ - tgui->accel.fg_col = (tgui->accel.fg_col & 0xff00) | val; - break; - case 0x2d: /*Foreground colour*/ - tgui->accel.fg_col = (tgui->accel.fg_col & 0xff) | (val << 8); - break; - - case 0x30: /*Background colour*/ - tgui->accel.bg_col = (tgui->accel.bg_col & 0xff00) | val; - break; - case 0x31: /*Background colour*/ - tgui->accel.bg_col = (tgui->accel.bg_col & 0xff) | (val << 8); - break; - - case 0x38: /*Dest X*/ - tgui->accel.dst_x = (tgui->accel.dst_x & 0xff00) | val; - break; - case 0x39: /*Dest X*/ - tgui->accel.dst_x = (tgui->accel.dst_x & 0xff) | (val << 8); - break; - case 0x3a: /*Dest Y*/ - tgui->accel.dst_y = (tgui->accel.dst_y & 0xff00) | val; - break; - case 0x3b: /*Dest Y*/ - tgui->accel.dst_y = (tgui->accel.dst_y & 0xff) | (val << 8); - break; - - case 0x3c: /*Src X*/ - tgui->accel.src_x = (tgui->accel.src_x & 0xff00) | val; - break; - case 0x3d: /*Src X*/ - tgui->accel.src_x = (tgui->accel.src_x & 0xff) | (val << 8); - break; - case 0x3e: /*Src Y*/ - tgui->accel.src_y = (tgui->accel.src_y & 0xff00) | val; - break; - case 0x3f: /*Src Y*/ - tgui->accel.src_y = (tgui->accel.src_y & 0xff) | (val << 8); - break; - - case 0x40: /*Size X*/ - tgui->accel.size_x = (tgui->accel.size_x & 0xff00) | val; - break; - case 0x41: /*Size X*/ - tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); - break; - case 0x42: /*Size Y*/ - tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; - break; - case 0x43: /*Size Y*/ - tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8); - break; - - case 0x80: case 0x81: case 0x82: case 0x83: - case 0x84: case 0x85: case 0x86: case 0x87: - case 0x88: case 0x89: case 0x8a: case 0x8b: - case 0x8c: case 0x8d: case 0x8e: case 0x8f: - case 0x90: case 0x91: case 0x92: case 0x93: - case 0x94: case 0x95: case 0x96: case 0x97: - case 0x98: case 0x99: case 0x9a: case 0x9b: - case 0x9c: case 0x9d: case 0x9e: case 0x9f: - case 0xa0: case 0xa1: case 0xa2: case 0xa3: - case 0xa4: case 0xa5: case 0xa6: case 0xa7: - case 0xa8: case 0xa9: case 0xaa: case 0xab: - case 0xac: case 0xad: case 0xae: case 0xaf: - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - case 0xb4: case 0xb5: case 0xb6: case 0xb7: - case 0xb8: case 0xb9: case 0xba: case 0xbb: - case 0xbc: case 0xbd: case 0xbe: case 0xbf: - case 0xc0: case 0xc1: case 0xc2: case 0xc3: - case 0xc4: case 0xc5: case 0xc6: case 0xc7: - case 0xc8: case 0xc9: case 0xca: case 0xcb: - case 0xcc: case 0xcd: case 0xce: case 0xcf: - case 0xd0: case 0xd1: case 0xd2: case 0xd3: - case 0xd4: case 0xd5: case 0xd6: case 0xd7: - case 0xd8: case 0xd9: case 0xda: case 0xdb: - case 0xdc: case 0xdd: case 0xde: case 0xdf: - case 0xe0: case 0xe1: case 0xe2: case 0xe3: - case 0xe4: case 0xe5: case 0xe6: case 0xe7: - case 0xe8: case 0xe9: case 0xea: case 0xeb: - case 0xec: case 0xed: case 0xee: case 0xef: - case 0xf0: case 0xf1: case 0xf2: case 0xf3: - case 0xf4: case 0xf5: case 0xf6: case 0xf7: - case 0xf8: case 0xf9: case 0xfa: case 0xfb: - case 0xfc: case 0xfd: case 0xfe: case 0xff: - tgui->accel.pattern[addr & 0x7f] = val; - break; - } -} - -static void tgui_accel_write_fifo_fb_b(tgui_t *tgui, uint32_t addr, uint8_t val) -{ - tgui_accel_command(8, val << 24, tgui); -} -static void tgui_accel_write_fifo_fb_w(tgui_t *tgui, uint32_t addr, uint16_t val) -{ - tgui_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16, tgui); -} -static void tgui_accel_write_fifo_fb_l(tgui_t *tgui, uint32_t addr, uint32_t val) -{ - tgui_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), tgui); -} - -static void fifo_thread(void *param) -{ - tgui_t *tgui = (tgui_t *)param; - - while (1) - { - thread_set_event(tgui->fifo_not_full_event); - thread_wait_event(tgui->wake_fifo_thread, -1); - thread_reset_event(tgui->wake_fifo_thread); - tgui->blitter_busy = 1; - while (!FIFO_EMPTY) - { - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &tgui->fifo[tgui->fifo_read_idx & FIFO_MASK]; - - switch (fifo->addr_type & FIFO_TYPE) - { - case FIFO_WRITE_BYTE: - tgui_accel_write_fifo(tgui, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_FB_BYTE: - tgui_accel_write_fifo_fb_b(tgui, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_FB_WORD: - tgui_accel_write_fifo_fb_w(tgui, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_FB_LONG: - tgui_accel_write_fifo_fb_l(tgui, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - } - - tgui->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; - - if (FIFO_ENTRIES > 0xe000) - thread_set_event(tgui->fifo_not_full_event); - - end_time = plat_timer_read(); - tgui->blitter_time += end_time - start_time; - } - tgui->blitter_busy = 0; - } -} - -static inline void wake_fifo_thread(tgui_t *tgui) -{ - thread_set_event(tgui->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ -} - -static void tgui_wait_fifo_idle(tgui_t *tgui) -{ - while (!FIFO_EMPTY) - { - wake_fifo_thread(tgui); - thread_wait_event(tgui->fifo_not_full_event, 1); - } -} - -static void tgui_queue(tgui_t *tgui, uint32_t addr, uint32_t val, uint32_t type) -{ - fifo_entry_t *fifo = &tgui->fifo[tgui->fifo_write_idx & FIFO_MASK]; - - if (FIFO_FULL) - { - thread_reset_event(tgui->fifo_not_full_event); - if (FIFO_FULL) - { - thread_wait_event(tgui->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } - - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; - - tgui->fifo_write_idx++; - - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(tgui); -} - - -void tgui_accel_write(uint32_t addr, uint8_t val, void *p) -{ - tgui_t *tgui = (tgui_t *)p; - if ((addr & ~0xff) != 0xbff00) - return; - tgui_queue(tgui, addr, val, FIFO_WRITE_BYTE); -} - -void tgui_accel_write_w(uint32_t addr, uint16_t val, void *p) -{ - tgui_t *tgui = (tgui_t *)p; - tgui_accel_write(addr, val, tgui); - tgui_accel_write(addr + 1, val >> 8, tgui); -} - -void tgui_accel_write_l(uint32_t addr, uint32_t val, void *p) -{ - tgui_t *tgui = (tgui_t *)p; - tgui_accel_write(addr, val, tgui); - tgui_accel_write(addr + 1, val >> 8, tgui); - tgui_accel_write(addr + 2, val >> 16, tgui); - tgui_accel_write(addr + 3, val >> 24, tgui); -} - -uint8_t tgui_accel_read(uint32_t addr, void *p) -{ - tgui_t *tgui = (tgui_t *)p; - if ((addr & ~0xff) != 0xbff00) - return 0xff; - if ((addr & 0xff) != 0x20) - tgui_wait_fifo_idle(tgui); - switch (addr & 0xff) - { - case 0x20: /*Status*/ - if (!FIFO_EMPTY) - return 1 << 5; - return 0; - - case 0x27: /*ROP*/ - return tgui->accel.rop; - - case 0x28: /*Flags*/ - return tgui->accel.flags & 0xff; - case 0x29: /*Flags*/ - return tgui->accel.flags >> 8; - - case 0x2b: - return tgui->accel.offset; - - case 0x2c: /*Background colour*/ - return tgui->accel.bg_col & 0xff; - case 0x2d: /*Background colour*/ - return tgui->accel.bg_col >> 8; - - case 0x30: /*Foreground colour*/ - return tgui->accel.fg_col & 0xff; - case 0x31: /*Foreground colour*/ - return tgui->accel.fg_col >> 8; - - case 0x38: /*Dest X*/ - return tgui->accel.dst_x & 0xff; - case 0x39: /*Dest X*/ - return tgui->accel.dst_x >> 8; - case 0x3a: /*Dest Y*/ - return tgui->accel.dst_y & 0xff; - case 0x3b: /*Dest Y*/ - return tgui->accel.dst_y >> 8; - - case 0x3c: /*Src X*/ - return tgui->accel.src_x & 0xff; - case 0x3d: /*Src X*/ - return tgui->accel.src_x >> 8; - case 0x3e: /*Src Y*/ - return tgui->accel.src_y & 0xff; - case 0x3f: /*Src Y*/ - return tgui->accel.src_y >> 8; - - case 0x40: /*Size X*/ - return tgui->accel.size_x & 0xff; - case 0x41: /*Size X*/ - return tgui->accel.size_x >> 8; - case 0x42: /*Size Y*/ - return tgui->accel.size_y & 0xff; - case 0x43: /*Size Y*/ - return tgui->accel.size_y >> 8; - - case 0x80: case 0x81: case 0x82: case 0x83: - case 0x84: case 0x85: case 0x86: case 0x87: - case 0x88: case 0x89: case 0x8a: case 0x8b: - case 0x8c: case 0x8d: case 0x8e: case 0x8f: - case 0x90: case 0x91: case 0x92: case 0x93: - case 0x94: case 0x95: case 0x96: case 0x97: - case 0x98: case 0x99: case 0x9a: case 0x9b: - case 0x9c: case 0x9d: case 0x9e: case 0x9f: - case 0xa0: case 0xa1: case 0xa2: case 0xa3: - case 0xa4: case 0xa5: case 0xa6: case 0xa7: - case 0xa8: case 0xa9: case 0xaa: case 0xab: - case 0xac: case 0xad: case 0xae: case 0xaf: - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - case 0xb4: case 0xb5: case 0xb6: case 0xb7: - case 0xb8: case 0xb9: case 0xba: case 0xbb: - case 0xbc: case 0xbd: case 0xbe: case 0xbf: - case 0xc0: case 0xc1: case 0xc2: case 0xc3: - case 0xc4: case 0xc5: case 0xc6: case 0xc7: - case 0xc8: case 0xc9: case 0xca: case 0xcb: - case 0xcc: case 0xcd: case 0xce: case 0xcf: - case 0xd0: case 0xd1: case 0xd2: case 0xd3: - case 0xd4: case 0xd5: case 0xd6: case 0xd7: - case 0xd8: case 0xd9: case 0xda: case 0xdb: - case 0xdc: case 0xdd: case 0xde: case 0xdf: - case 0xe0: case 0xe1: case 0xe2: case 0xe3: - case 0xe4: case 0xe5: case 0xe6: case 0xe7: - case 0xe8: case 0xe9: case 0xea: case 0xeb: - case 0xec: case 0xed: case 0xee: case 0xef: - case 0xf0: case 0xf1: case 0xf2: case 0xf3: - case 0xf4: case 0xf5: case 0xf6: case 0xf7: - case 0xf8: case 0xf9: case 0xfa: case 0xfb: - case 0xfc: case 0xfd: case 0xfe: case 0xff: - return tgui->accel.pattern[addr & 0x7f]; - } - return 0xff; -} - -uint16_t tgui_accel_read_w(uint32_t addr, void *p) -{ - tgui_t *tgui = (tgui_t *)p; - return tgui_accel_read(addr, tgui) | (tgui_accel_read(addr + 1, tgui) << 8); -} - -uint32_t tgui_accel_read_l(uint32_t addr, void *p) -{ - tgui_t *tgui = (tgui_t *)p; - return tgui_accel_read_w(addr, tgui) | (tgui_accel_read_w(addr + 2, tgui) << 16); -} - -void tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; - - if (tgui->write_blitter) - tgui_queue(tgui, addr, val, FIFO_WRITE_FB_BYTE); - else - svga_write_linear(addr, val, svga); -} - -void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; - - if (tgui->write_blitter) - tgui_queue(tgui, addr, val, FIFO_WRITE_FB_WORD); - else - svga_writew_linear(addr, val, svga); -} - -void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; - - if (tgui->write_blitter) - tgui_queue(tgui, addr, val, FIFO_WRITE_FB_LONG); - else - svga_writel_linear(addr, val, svga); -} - -static const device_config_t tgui9440_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } -}; - -const device_t tgui9400cxi_device = -{ - "Trident TGUI 9400CXi", - DEVICE_VLB, - 0, - tgui9400cxi_init, - tgui_close, - NULL, - tgui9400cxi_available, - tgui_speed_changed, - tgui_force_redraw, - tgui9440_config -}; - -const device_t tgui9440_vlb_device = -{ - "Trident TGUI 9440 VLB", - DEVICE_VLB, - 0, - tgui9440_init, - tgui_close, - NULL, - tgui9440_available, - tgui_speed_changed, - tgui_force_redraw, - tgui9440_config -}; - -const device_t tgui9440_pci_device = -{ - "Trident TGUI 9440 PCI", - DEVICE_PCI, - 0, - tgui9440_init, - tgui_close, - NULL, - tgui9440_available, - tgui_speed_changed, - tgui_force_redraw, - tgui9440_config -}; \ No newline at end of file diff --git a/backup code/video - Cópia/vid_tgui9440.h b/backup code/video - Cópia/vid_tgui9440.h deleted file mode 100644 index 24208e913..000000000 --- a/backup code/video - Cópia/vid_tgui9440.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t tgui9400cxi_device; -extern const device_t tgui9440_vlb_device; -extern const device_t tgui9440_pci_device; diff --git a/backup code/video - Cópia/vid_ti_cf62011.c b/backup code/video - Cópia/vid_ti_cf62011.c deleted file mode 100644 index d3ec979f1..000000000 --- a/backup code/video - Cópia/vid_ti_cf62011.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * 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 TI CF62011 SVGA chip. - * - * This chip was used in several of IBM's later machines, such - * as the PS/1 Model 2121, and a number of PS/2 models. As noted - * in an article on Usenet: - * - * "In the early 90s IBM looked for some cheap VGA card to - * substitute the (relatively) expensive XGA-2 adapter for - * *servers*, where the primary purpose is supervision of the - * machine rather than real *work* with it in Hi-Res. It was - * just to supply a base video, where a XGA-2 were a waste of - * potential. They had a contract with TI for some DSPs in - * multimedia already (the MWave for instance is based on - * TI-DSPs as well as many Thinkpad internal chipsets) and TI - * offered them a rather cheap – and inexpensive – chipset - * and combined it with a cheap clock oscillator and an Inmos - * RAMDAC. That chipset was already pretty much outdated at - * that time but IBM decided it would suffice for that low - * end purpose. - * - * Driver support was given under DOS and OS/2 only for base - * functions like selection of the vertical refresh and few - * different modes only. Not even the Win 3.x support has - * been finalized. Technically the adapter could do better - * than VGA, but its video BIOS is largely undocumented and - * intentionally crippled down to a few functions." - * - * This chip is reportedly the same one as used in the MCA - * IBM SVGA Adapter/A (ID 090EEh), which mostly had faster - * VRAM and RAMDAC. The VESA DOS graphics driver for that - * card can be used: m95svga.exe - * - * The controller responds at ports in the range 0x2100-0x210F, - * which are the same as the XGA. It supports up to 1MB of VRAM, - * but we lock it down to 512K. The PS/1 2122 had 256K. - * - * Version: @(#)vid_ti_cf62011.c 1.0.7 2018/04/29 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../config.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../video/video.h" -#include "../video/vid_vga.h" -#include "../video/vid_svga.h" -#include "vid_ti_cf62011.h" - - -typedef struct { - svga_t svga; - - rom_t bios_rom; - - int enabled; - - uint32_t vram_size; - - uint8_t banking; - uint8_t reg_2100; - uint8_t reg_210a; -} tivga_t; - - -static void -vid_out(uint16_t addr, uint8_t val, void *priv) -{ - tivga_t *ti = (tivga_t *)priv; - svga_t *svga = &ti->svga; - uint8_t old; - -#if 0 - if (((addr & 0xfff0) == 0x03d0 || (addr & 0xfff0) == 0x03b0) && - !(svga->miscout & 1)) addr ^= 0x60; -#endif - - switch (addr) { - case 0x0102: - ti->enabled = (val & 0x01); - return; - - case 0x03d4: - svga->crtcreg = val & 0x3f; - return; - - case 0x03d5: - if (svga->crtcreg & 0x20) - return; - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - - case 0x2100: - ti->reg_2100 = val; - if ((val & 7) < 4) - svga->read_bank = svga->write_bank = 0; - else - svga->read_bank = svga->write_bank = (ti->banking & 0x7) * 0x10000; - break; - - case 0x2108: - if ((ti->reg_2100 & 7) >= 4) - svga->read_bank = svga->write_bank = (val & 0x7) * 0x10000; - ti->banking = val; - break; - - case 0x210a: - ti->reg_210a = val; - break; - } - - svga_out(addr, val, svga); -} - - -static uint8_t -vid_in(uint16_t addr, void *priv) -{ - tivga_t *ti = (tivga_t *)priv; - svga_t *svga = &ti->svga; - uint8_t ret; - -#if 0 - if (((addr & 0xfff0) == 0x03d0 || (addr & 0xfff0) == 0x03b0) && - !(svga->miscout & 1)) addr ^= 0x60; -#endif - - switch (addr) { - case 0x0100: - ret = 0xfe; - break; - - case 0x0101: - ret = 0xe8; - break; - - case 0x0102: - ret = ti->enabled; - break; - - case 0x03d4: - ret = svga->crtcreg; - break; - - case 0x03d5: - if (svga->crtcreg & 0x20) - ret = 0xff; - else - ret = svga->crtc[svga->crtcreg]; - break; - - case 0x2100: - ret = ti->reg_2100; - break; - - case 0x2108: - ret = ti->banking; - break; - - case 0x210a: - ret = ti->reg_210a; - break; - - default: - ret = svga_in(addr, svga); - break; - } - - return(ret); -} - - -static void -vid_speed_changed(void *priv) -{ - tivga_t *ti = (tivga_t *)priv; - - svga_recalctimings(&ti->svga); -} - - -static void -vid_force_redraw(void *priv) -{ - tivga_t *ti = (tivga_t *)priv; - - ti->svga.fullchange = changeframecount; -} - - -static void -vid_close(void *priv) -{ - tivga_t *ti = (tivga_t *)priv; - - svga_close(&ti->svga); - - free(ti); -} - - -static void * -vid_init(const device_t *info) -{ - tivga_t *ti; - - /* Allocate control block and initialize. */ - ti = (tivga_t *)malloc(sizeof(tivga_t)); - memset(ti, 0x00, sizeof(tivga_t)); - - /* Set amount of VRAM in KB. */ - if (info->local == 0) - ti->vram_size = device_get_config_int("vram_size"); - else - ti->vram_size = info->local; - - svga_init(&ti->svga, ti, - ti->vram_size<<10, - NULL, vid_in, vid_out, NULL, NULL); - - io_sethandler(0x0100, 2, vid_in, NULL, NULL, NULL, NULL, NULL, ti); - io_sethandler(0x03c0, 32, vid_in, NULL, NULL, vid_out, NULL, NULL, ti); - io_sethandler(0x2100, 16, vid_in, NULL, NULL, vid_out, NULL, NULL, ti); - - ti->svga.bpp = 8; - ti->svga.miscout = 1; - - return(ti); -} - - -#if defined(DEV_BRANCH) && defined(USE_TI) -static const device_config_t vid_config[] = -{ - { - "vram_size", "Memory Size", CONFIG_SELECTION, "", 256, - { - { - "256K", 256 - }, - { - "512K", 512 - }, - { - "1024K", 1024 - }, - { - "" - } - } - }, - { - "", "", -1 - } -}; - - -const device_t ti_cf62011_device = { - "TI CF62011 SVGA", - 0, - 0, - vid_init, vid_close, NULL, - NULL, - vid_speed_changed, - vid_force_redraw, - vid_config -}; -#endif - - -const device_t ibm_ps1_2121_device = { - "IBM PS/1 Model 2121 SVGA", - 0, - 512, - vid_init, vid_close, NULL, - NULL, - vid_speed_changed, - vid_force_redraw, - NULL -}; diff --git a/backup code/video - Cópia/vid_ti_cf62011.h b/backup code/video - Cópia/vid_ti_cf62011.h deleted file mode 100644 index 185f98511..000000000 --- a/backup code/video - Cópia/vid_ti_cf62011.h +++ /dev/null @@ -1,4 +0,0 @@ -#if defined(DEV_BRANCH) && defined(USE_TI) -extern const device_t ti_cf62011_device; -#endif -extern const device_t ibm_ps1_2121_device; diff --git a/backup code/video - Cópia/vid_tkd8001_ramdac.c b/backup code/video - Cópia/vid_tkd8001_ramdac.c deleted file mode 100644 index e2d266cac..000000000 --- a/backup code/video - Cópia/vid_tkd8001_ramdac.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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. - * - * Trident TKD8001 RAMDAC emulation. - * - * Version: @(#)vid_tkd8001_ramdac.c 1.0.2 2017/11/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_tkd8001_ramdac.h" - - -void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga) -{ - switch (addr) - { - case 0x3C6: - if (ramdac->state == 4) - { - ramdac->state = 0; - ramdac->ctrl = val; - switch (val >> 5) - { - case 0: case 1: case 2: case 3: - svga->bpp = 8; - break; - case 5: - svga->bpp = 15; - break; - case 6: - svga->bpp = 24; - break; - case 7: - svga->bpp = 16; - break; - } - return; - } - break; - case 0x3C7: case 0x3C8: case 0x3C9: - ramdac->state = 0; - break; - } - svga_out(addr, val, svga); -} - -uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga) -{ - switch (addr) - { - case 0x3C6: - if (ramdac->state == 4) - { - return ramdac->ctrl; - } - ramdac->state++; - break; - case 0x3C7: case 0x3C8: case 0x3C9: - ramdac->state = 0; - break; - } - return svga_in(addr, svga); -} diff --git a/backup code/video - Cópia/vid_tkd8001_ramdac.h b/backup code/video - Cópia/vid_tkd8001_ramdac.h deleted file mode 100644 index f83ba978d..000000000 --- a/backup code/video - Cópia/vid_tkd8001_ramdac.h +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -typedef struct tkd8001_ramdac_t -{ - int state; - uint8_t ctrl; -} tkd8001_ramdac_t; - -void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga); -uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga); diff --git a/backup code/video - Cópia/vid_tvga.c b/backup code/video - Cópia/vid_tvga.c deleted file mode 100644 index 84bc2421e..000000000 --- a/backup code/video - Cópia/vid_tvga.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * 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. - * - * Trident TVGA (8900D) emulation. - * - * Version: @(#)vid_tvga.c 1.0.6 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_svga_render.h" -#include "vid_tkd8001_ramdac.h" -#include "vid_tvga.h" - - -typedef struct tvga_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t accel_mapping; - - svga_t svga; - tkd8001_ramdac_t ramdac; - - rom_t bios_rom; - - uint8_t tvga_3d8, tvga_3d9; - int oldmode; - uint8_t oldctrl1; - uint8_t oldctrl2, newctrl2; - - int vram_size; - uint32_t vram_mask; -} tvga_t; - -static uint8_t crtc_mask[0x40] = -{ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x7f, 0xff, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xef, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x7f, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static void tvga_recalcbanking(tvga_t *tvga); -void tvga_out(uint16_t addr, uint8_t val, void *p) -{ - tvga_t *tvga = (tvga_t *)p; - svga_t *svga = &tvga->svga; - - uint8_t old; - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; - - switch (addr) - { - case 0x3C5: - switch (svga->seqaddr & 0xf) - { - case 0xB: - tvga->oldmode=1; - break; - case 0xC: - if (svga->seqregs[0xe] & 0x80) - svga->seqregs[0xc] = val; - break; - case 0xd: - if (tvga->oldmode) - tvga->oldctrl2 = val; - else - { - tvga->newctrl2 = val; - svga_recalctimings(svga); - } - break; - case 0xE: - if (tvga->oldmode) - tvga->oldctrl1 = val; - else - { - svga->seqregs[0xe] = val ^ 2; - tvga->tvga_3d8 = svga->seqregs[0xe] & 0xf; - tvga_recalcbanking(tvga); - } - return; - } - break; - - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - tkd8001_ramdac_out(addr, val, &tvga->ramdac, svga); - return; - - case 0x3CF: - switch (svga->gdcaddr & 15) - { - case 0xE: - svga->gdcreg[0xe] = val ^ 2; - tvga->tvga_3d9 = svga->gdcreg[0xe] & 0xf; - tvga_recalcbanking(tvga); - break; - case 0xF: - svga->gdcreg[0xf] = val; - tvga_recalcbanking(tvga); - break; - } - break; - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - val &= crtc_mask[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) - { - if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - switch (svga->crtcreg) - { - case 0x1e: - svga->vram_display_mask = (val & 0x80) ? tvga->vram_mask : 0x3ffff; - break; - } - return; - case 0x3D8: - if (svga->gdcreg[0xf] & 4) - { - tvga->tvga_3d8 = val; - tvga_recalcbanking(tvga); - } - return; - case 0x3D9: - if (svga->gdcreg[0xf] & 4) - { - tvga->tvga_3d9 = val; - tvga_recalcbanking(tvga); - } - return; - } - svga_out(addr, val, svga); -} - -uint8_t tvga_in(uint16_t addr, void *p) -{ - tvga_t *tvga = (tvga_t *)p; - svga_t *svga = &tvga->svga; - - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; - - switch (addr) - { - case 0x3C5: - if ((svga->seqaddr & 0xf) == 0xb) - { - tvga->oldmode = 0; - return 0x33; /*TVGA8900D*/ - } - if ((svga->seqaddr & 0xf) == 0xd) - { - if (tvga->oldmode) return tvga->oldctrl2; - return tvga->newctrl2; - } - if ((svga->seqaddr & 0xf) == 0xe) - { - if (tvga->oldmode) - return tvga->oldctrl1; - } - break; - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - return tkd8001_ramdac_in(addr, &tvga->ramdac, svga); - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - if (svga->crtcreg > 0x18 && svga->crtcreg < 0x1e) - return 0xff; - return svga->crtc[svga->crtcreg]; - case 0x3d8: - return tvga->tvga_3d8; - case 0x3d9: - return tvga->tvga_3d9; - } - return svga_in(addr, svga); -} - -static void tvga_recalcbanking(tvga_t *tvga) -{ - svga_t *svga = &tvga->svga; - - svga->write_bank = (tvga->tvga_3d8 & 0x1f) * 65536; - - if (svga->gdcreg[0xf] & 1) - svga->read_bank = (tvga->tvga_3d9 & 0x1f) * 65536; - else - svga->read_bank = svga->write_bank; -} - -void tvga_recalctimings(svga_t *svga) -{ - tvga_t *tvga = (tvga_t *)svga->p; - if (!svga->rowoffset) svga->rowoffset = 0x100; /*This is the only sensible way I can see this being handled, - given that TVGA8900D has no overflow bits. - Some sort of overflow is required for 320x200x24 and 1024x768x16*/ - if (svga->crtc[0x29] & 0x10) - svga->rowoffset += 0x100; - - if (svga->bpp == 24) - svga->hdisp = (svga->crtc[1] + 1) * 8; - - if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000; - if ((svga->crtc[0x27] & 0x01) == 0x01) svga->ma_latch |= 0x20000; - if ((svga->crtc[0x27] & 0x02) == 0x02) svga->ma_latch |= 0x40000; - - if (tvga->oldctrl2 & 0x10) - { - svga->rowoffset <<= 1; - svga->ma_latch <<= 1; - } - if (svga->gdcreg[0xf] & 0x08) - { - svga->htotal *= 2; - svga->hdisp *= 2; - svga->hdisp_time *= 2; - } - - svga->interlace = (svga->crtc[0x1e] & 4); - - if (svga->interlace) - svga->rowoffset >>= 1; - - switch (((svga->miscout >> 2) & 3) | ((tvga->newctrl2 << 2) & 4)) - { - case 2: svga->clock = cpuclock/44900000.0; break; - case 3: svga->clock = cpuclock/36000000.0; break; - case 4: svga->clock = cpuclock/57272000.0; break; - case 5: svga->clock = cpuclock/65000000.0; break; - case 6: svga->clock = cpuclock/50350000.0; break; - case 7: svga->clock = cpuclock/40000000.0; break; - } - - if (tvga->oldctrl2 & 0x10) - { - switch (svga->bpp) - { - case 8: - svga->render = svga_render_8bpp_highres; - break; - case 15: - svga->render = svga_render_15bpp_highres; - svga->hdisp /= 2; - break; - case 16: - svga->render = svga_render_16bpp_highres; - svga->hdisp /= 2; - break; - case 24: - svga->render = svga_render_24bpp_highres; - svga->hdisp /= 3; - break; - } - svga->lowres = 0; - } -} - - -static void *tvga8900d_init(const device_t *info) -{ - tvga_t *tvga = malloc(sizeof(tvga_t)); - memset(tvga, 0, sizeof(tvga_t)); - - tvga->vram_size = device_get_config_int("memory") << 10; - tvga->vram_mask = tvga->vram_size - 1; - - rom_init(&tvga->bios_rom, L"roms/video/tvga/trident.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - svga_init(&tvga->svga, tvga, tvga->vram_size, - tvga_recalctimings, - tvga_in, tvga_out, - NULL, - NULL); - - io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga); - - return tvga; -} - -static int tvga8900d_available(void) -{ - return rom_present(L"roms/video/tvga/trident.bin"); -} - -void tvga_close(void *p) -{ - tvga_t *tvga = (tvga_t *)p; - - svga_close(&tvga->svga); - - free(tvga); -} - -void tvga_speed_changed(void *p) -{ - tvga_t *tvga = (tvga_t *)p; - - svga_recalctimings(&tvga->svga); -} - -void tvga_force_redraw(void *p) -{ - tvga_t *tvga = (tvga_t *)p; - - tvga->svga.fullchange = changeframecount; -} - -static const device_config_t tvga_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 1024, - { - { - "256 kB", 256 - }, - { - "512 kB", 512 - }, - { - "1 MB", 1024 - }, - /*Chip supports 2mb, but drivers are buggy*/ - { - "" - } - } - }, - { - "", "", -1 - } -}; - -const device_t tvga8900d_device = -{ - "Trident TVGA 8900D", - DEVICE_ISA, - 0, - tvga8900d_init, - tvga_close, - NULL, - tvga8900d_available, - tvga_speed_changed, - tvga_force_redraw, - tvga_config -}; diff --git a/backup code/video - Cópia/vid_tvga.h b/backup code/video - Cópia/vid_tvga.h deleted file mode 100644 index 43e1b778b..000000000 --- a/backup code/video - Cópia/vid_tvga.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t tvga8900d_device; diff --git a/backup code/video - Cópia/vid_vga.c b/backup code/video - Cópia/vid_vga.c deleted file mode 100644 index 5ea76dc83..000000000 --- a/backup code/video - Cópia/vid_vga.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * 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. - * - * IBM VGA emulation. - * - * Version: @(#)vid_vga.c 1.0.5 2018/04/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_vga.h" - - -typedef struct vga_t -{ - svga_t svga; - - rom_t bios_rom; -} vga_t; - -void vga_out(uint16_t addr, uint8_t val, void *p) -{ - vga_t *vga = (vga_t *)p; - svga_t *svga = &vga->svga; - uint8_t old; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if (svga->crtcreg & 0x20) - return; - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); -} - -uint8_t vga_in(uint16_t addr, void *p) -{ - vga_t *vga = (vga_t *)p; - svga_t *svga = &vga->svga; - uint8_t temp; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3D4: - temp = svga->crtcreg; - break; - case 0x3D5: - if (svga->crtcreg & 0x20) - temp = 0xff; - else - temp = svga->crtc[svga->crtcreg]; - break; - default: - temp = svga_in(addr, svga); - break; - } - return temp; -} - - -static void *vga_init(const device_t *info) -{ - vga_t *vga = malloc(sizeof(vga_t)); - memset(vga, 0, sizeof(vga_t)); - - rom_init(&vga->bios_rom, L"roms/video/vga/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); - - svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ - NULL, - vga_in, vga_out, - NULL, - NULL); - - io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); - - vga->svga.bpp = 8; - vga->svga.miscout = 1; - - return vga; -} - - -#ifdef DEV_BRANCH -static void *trigem_unk_init(const device_t *info) -{ - vga_t *vga = malloc(sizeof(vga_t)); - memset(vga, 0, sizeof(vga_t)); - - rom_init(&vga->bios_rom, L"roms/video/vga/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); - - svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ - NULL, - vga_in, vga_out, - NULL, - NULL); - - io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); - - io_sethandler(0x22ca, 0x0002, svga_in, NULL, NULL, vga_out, NULL, NULL, vga); - io_sethandler(0x22ce, 0x0002, svga_in, NULL, NULL, vga_out, NULL, NULL, vga); - io_sethandler(0x32ca, 0x0002, svga_in, NULL, NULL, vga_out, NULL, NULL, vga); - - vga->svga.bpp = 8; - vga->svga.miscout = 1; - - return vga; -} -#endif - -/*PS/1 uses a standard VGA controller, but with no option ROM*/ -void *ps1vga_init(const device_t *info) -{ - vga_t *vga = malloc(sizeof(vga_t)); - memset(vga, 0, sizeof(vga_t)); - - svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ - NULL, - vga_in, vga_out, - NULL, - NULL); - - io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); - - vga->svga.bpp = 8; - vga->svga.miscout = 1; - - return vga; -} - -static int vga_available(void) -{ - return rom_present(L"roms/video/vga/ibm_vga.bin"); -} - -void vga_close(void *p) -{ - vga_t *vga = (vga_t *)p; - - svga_close(&vga->svga); - - free(vga); -} - -void vga_speed_changed(void *p) -{ - vga_t *vga = (vga_t *)p; - - svga_recalctimings(&vga->svga); -} - -void vga_force_redraw(void *p) -{ - vga_t *vga = (vga_t *)p; - - vga->svga.fullchange = changeframecount; -} - -const device_t vga_device = -{ - "VGA", - DEVICE_ISA, - 0, - vga_init, - vga_close, - NULL, - vga_available, - vga_speed_changed, - vga_force_redraw, - NULL -}; -#ifdef DEV_BRANCH -const device_t trigem_unk_device = -{ - "VGA", - DEVICE_ISA, - 0, - trigem_unk_init, - vga_close, - NULL, - vga_available, - vga_speed_changed, - vga_force_redraw, - NULL -}; -#endif -const device_t ps1vga_device = -{ - "PS/1 VGA", - 0, - 0, - ps1vga_init, - vga_close, - NULL, - vga_available, - vga_speed_changed, - vga_force_redraw, - NULL -}; diff --git a/backup code/video - Cópia/vid_vga.h b/backup code/video - Cópia/vid_vga.h deleted file mode 100644 index 44fa836fb..000000000 --- a/backup code/video - Cópia/vid_vga.h +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t vga_device; -#ifdef DEV_BRANCH -extern const device_t trigem_unk_device; -#endif -extern const device_t ps1vga_device; diff --git a/backup code/video - Cópia/vid_voodoo.c b/backup code/video - Cópia/vid_voodoo.c deleted file mode 100644 index 1bbdcc64a..000000000 --- a/backup code/video - Cópia/vid_voodoo.c +++ /dev/null @@ -1,7888 +0,0 @@ -/* - * 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 3DFX Voodoo Graphics controller. - * - * Version: @(#)vid_voodoo.c 1.0.14 2018/04/26 - * - * Authors: Sarah Walker, - * leilei - * - * Copyright 2008-2018 Sarah Walker. - */ -#include -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../device.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../plat.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_voodoo.h" -#include "vid_voodoo_dither.h" - -#ifdef CLAMP -#undef CLAMP -#endif - -#define CLAMP(x) (((x) < 0) ? 0 : (((x) > 0xff) ? 0xff : (x))) -#define CLAMP16(x) (((x) < 0) ? 0 : (((x) > 0xffff) ? 0xffff : (x))) - -#define LOD_MAX 8 - -#define TEX_DIRTY_SHIFT 10 - -#define TEX_CACHE_MAX 64 - -enum -{ - VOODOO_1 = 0, - VOODOO_SB50 = 1, - VOODOO_2 = 2 -}; - -static uint32_t texture_offset[LOD_MAX+3] = -{ - 0, - 256*256, - 256*256 + 128*128, - 256*256 + 128*128 + 64*64, - 256*256 + 128*128 + 64*64 + 32*32, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2 + 1*1, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2 + 1*1 + 1 -}; - -static int tris = 0; - -typedef union { - uint32_t i; - float f; -} int_float; - -typedef struct { - uint8_t b, g, r; - uint8_t pad; -} rgbp_t; -typedef struct { - uint8_t b, g, r, a; -} rgba8_t; - -typedef union { - struct { - uint8_t b, g, r, a; - } rgba; - uint32_t u; -} rgba_u; - -#define FIFO_SIZE 65536 -#define FIFO_MASK (FIFO_SIZE - 1) -#define FIFO_ENTRY_SIZE (1 << 31) - -#define FIFO_ENTRIES (voodoo->fifo_write_idx - voodoo->fifo_read_idx) -#define FIFO_FULL ((voodoo->fifo_write_idx - voodoo->fifo_read_idx) >= FIFO_SIZE-4) -#define FIFO_EMPTY (voodoo->fifo_read_idx == voodoo->fifo_write_idx) - -#define FIFO_TYPE 0xff000000 -#define FIFO_ADDR 0x00ffffff - -enum -{ - FIFO_INVALID = (0x00 << 24), - FIFO_WRITEL_REG = (0x01 << 24), - FIFO_WRITEW_FB = (0x02 << 24), - FIFO_WRITEL_FB = (0x03 << 24), - FIFO_WRITEL_TEX = (0x04 << 24) -}; - -#define PARAM_SIZE 1024 -#define PARAM_MASK (PARAM_SIZE - 1) -#define PARAM_ENTRY_SIZE (1 << 31) - -#define PARAM_ENTRIES_1 (voodoo->params_write_idx - voodoo->params_read_idx[0]) -#define PARAM_ENTRIES_2 (voodoo->params_write_idx - voodoo->params_read_idx[1]) -#define PARAM_FULL_1 ((voodoo->params_write_idx - voodoo->params_read_idx[0]) >= PARAM_SIZE) -#define PARAM_FULL_2 ((voodoo->params_write_idx - voodoo->params_read_idx[1]) >= PARAM_SIZE) -#define PARAM_EMPTY_1 (voodoo->params_read_idx[0] == voodoo->params_write_idx) -#define PARAM_EMPTY_2 (voodoo->params_read_idx[1] == voodoo->params_write_idx) - -typedef struct -{ - uint32_t addr_type; - uint32_t val; -} fifo_entry_t; - -static rgba8_t rgb332[0x100], ai44[0x100], rgb565[0x10000], argb1555[0x10000], argb4444[0x10000], ai88[0x10000]; - -typedef struct voodoo_params_t -{ - int command; - - int32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy; - - uint32_t startR, startG, startB, startZ, startA; - - int32_t dBdX, dGdX, dRdX, dAdX, dZdX; - - int32_t dBdY, dGdY, dRdY, dAdY, dZdY; - - int64_t startW, dWdX, dWdY; - - struct - { - int64_t startS, startT, startW, p1; - int64_t dSdX, dTdX, dWdX, p2; - int64_t dSdY, dTdY, dWdY, p3; - } tmu[2]; - - uint32_t color0, color1; - - uint32_t fbzMode; - uint32_t fbzColorPath; - - uint32_t fogMode; - rgbp_t fogColor; - struct - { - uint8_t fog, dfog; - } fogTable[64]; - - uint32_t alphaMode; - - uint32_t zaColor; - - int chromaKey_r, chromaKey_g, chromaKey_b; - uint32_t chromaKey; - - uint32_t textureMode[2]; - uint32_t tLOD[2]; - - uint32_t texBaseAddr[2], texBaseAddr1[2], texBaseAddr2[2], texBaseAddr38[2]; - - uint32_t tex_base[2][LOD_MAX+2]; - uint32_t tex_end[2][LOD_MAX+2]; - int tex_width[2]; - int tex_w_mask[2][LOD_MAX+2]; - int tex_w_nmask[2][LOD_MAX+2]; - int tex_h_mask[2][LOD_MAX+2]; - int tex_shift[2][LOD_MAX+2]; - int tex_lod[2][LOD_MAX+2]; - int tex_entry[2]; - int detail_max[2], detail_bias[2], detail_scale[2]; - - uint32_t draw_offset, aux_offset; - - int tformat[2]; - - int clipLeft, clipRight, clipLowY, clipHighY; - - int sign; - - uint32_t front_offset; - - uint32_t swapbufferCMD; - - uint32_t stipple; -} voodoo_params_t; - -typedef struct texture_t -{ - uint32_t base; - uint32_t tLOD; - volatile int refcount, refcount_r[2]; - int is16; - uint32_t palette_checksum; - uint32_t addr_start[4], addr_end[4]; - uint32_t *data; -} texture_t; - -typedef struct voodoo_t -{ - mem_mapping_t mapping; - - int pci_enable; - - uint8_t dac_data[8]; - int dac_reg, dac_reg_ff; - uint8_t dac_readdata; - uint16_t dac_pll_regs[16]; - - float pixel_clock; - int line_time; - - voodoo_params_t params; - - uint32_t fbiInit0, fbiInit1, fbiInit2, fbiInit3, fbiInit4; - uint32_t fbiInit5, fbiInit6, fbiInit7; /*Voodoo 2*/ - - uint32_t initEnable; - - uint32_t lfbMode; - - uint32_t memBaseAddr; - - int_float fvertexAx, fvertexAy, fvertexBx, fvertexBy, fvertexCx, fvertexCy; - - uint32_t front_offset, back_offset; - - uint32_t fb_read_offset, fb_write_offset; - - int row_width; - int block_width; - - uint8_t *fb_mem, *tex_mem[2]; - uint16_t *tex_mem_w[2]; - - int rgb_sel; - - uint32_t trexInit1[2]; - - uint32_t tmuConfig; - - int swap_count; - - int disp_buffer, draw_buffer; - int64_t timer_count; - - int line; - svga_t *svga; - - uint32_t backPorch; - uint32_t videoDimensions; - uint32_t hSync, vSync; - - int h_total, v_total, v_disp; - int h_disp; - int v_retrace; - - struct - { - uint32_t y[4], i[4], q[4]; - } nccTable[2][2]; - - rgba_u palette[2][256]; - - rgba_u ncc_lookup[2][2][256]; - int ncc_dirty[2]; - - thread_t *fifo_thread; - thread_t *render_thread[2]; - event_t *wake_fifo_thread; - event_t *wake_main_thread; - event_t *fifo_not_full_event; - event_t *render_not_full_event[2]; - event_t *wake_render_thread[2]; - - int voodoo_busy; - int render_voodoo_busy[2]; - - int render_threads; - int odd_even_mask; - - int pixel_count[2], texel_count[2], tri_count, frame_count; - int pixel_count_old[2], texel_count_old[2]; - int wr_count, rd_count, tex_count; - - int retrace_count; - int swap_interval; - uint32_t swap_offset; - int swap_pending; - - int bilinear_enabled; - - int fb_size; - uint32_t fb_mask; - - int texture_size; - uint32_t texture_mask; - - int dual_tmus; - int type; - - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; - volatile int cmd_read, cmd_written, cmd_written_fifo; - - voodoo_params_t params_buffer[PARAM_SIZE]; - volatile int params_read_idx[2], params_write_idx; - - uint32_t cmdfifo_base, cmdfifo_end; - int cmdfifo_rp; - volatile int cmdfifo_depth_rd, cmdfifo_depth_wr; - uint32_t cmdfifo_amin, cmdfifo_amax; - - uint32_t sSetupMode; - struct - { - float sVx, sVy; - float sRed, sGreen, sBlue, sAlpha; - float sVz, sWb; - float sW0, sS0, sT0; - float sW1, sS1, sT1; - } verts[4]; - int vertex_num; - int num_verticies; - - int flush; - - int scrfilter; - int scrfilterEnabled; - int scrfilterThreshold; - int scrfilterThresholdOld; - - uint32_t last_write_addr; - - uint32_t fbiPixelsIn; - uint32_t fbiChromaFail; - uint32_t fbiZFuncFail; - uint32_t fbiAFuncFail; - uint32_t fbiPixelsOut; - - uint32_t bltSrcBaseAddr; - uint32_t bltDstBaseAddr; - int bltSrcXYStride, bltDstXYStride; - uint32_t bltSrcChromaRange, bltDstChromaRange; - int bltSrcChromaMinR, bltSrcChromaMinG, bltSrcChromaMinB; - int bltSrcChromaMaxR, bltSrcChromaMaxG, bltSrcChromaMaxB; - int bltDstChromaMinR, bltDstChromaMinG, bltDstChromaMinB; - int bltDstChromaMaxR, bltDstChromaMaxG, bltDstChromaMaxB; - - int bltClipRight, bltClipLeft; - int bltClipHighY, bltClipLowY; - - int bltSrcX, bltSrcY; - int bltDstX, bltDstY; - int bltSizeX, bltSizeY; - int bltRop[4]; - uint16_t bltColorFg, bltColorBg; - - uint32_t bltCommand; - - struct - { - int dst_x, dst_y; - int cur_x; - int size_x, size_y; - int x_dir, y_dir; - int dst_stride; - } blt; - - rgbp_t clutData[33]; - int clutData_dirty; - rgbp_t clutData256[256]; - uint32_t video_16to32[0x10000]; - - uint8_t dirty_line[1024]; - int dirty_line_low, dirty_line_high; - - int fb_write_buffer, fb_draw_buffer; - int buffer_cutoff; - - int64_t read_time, write_time, burst_time; - - int64_t wake_timer; - - uint8_t thefilter[256][256]; // pixel filter, feeding from one or two - uint8_t thefilterg[256][256]; // for green - uint8_t thefilterb[256][256]; // for blue - - /* the voodoo adds purple lines for some reason */ - uint16_t purpleline[256][3]; - - texture_t texture_cache[2][TEX_CACHE_MAX]; - uint8_t texture_present[2][4096]; - int texture_last_removed; - - uint32_t palette_checksum[2]; - int palette_dirty[2]; - - uint64_t time; - int render_time[2]; - - int use_recompiler; - void *codegen_data; - - struct voodoo_set_t *set; -} voodoo_t; - -typedef struct voodoo_set_t -{ - voodoo_t *voodoos[2]; - - mem_mapping_t snoop_mapping; - - int nr_cards; -} voodoo_set_t; - -static inline void wait_for_render_thread_idle(voodoo_t *voodoo); - -enum -{ - SST_status = 0x000, - SST_intrCtrl = 0x004, - - SST_vertexAx = 0x008, - SST_vertexAy = 0x00c, - SST_vertexBx = 0x010, - SST_vertexBy = 0x014, - SST_vertexCx = 0x018, - SST_vertexCy = 0x01c, - - SST_startR = 0x0020, - SST_startG = 0x0024, - SST_startB = 0x0028, - SST_startZ = 0x002c, - SST_startA = 0x0030, - SST_startS = 0x0034, - SST_startT = 0x0038, - SST_startW = 0x003c, - - SST_dRdX = 0x0040, - SST_dGdX = 0x0044, - SST_dBdX = 0x0048, - SST_dZdX = 0x004c, - SST_dAdX = 0x0050, - SST_dSdX = 0x0054, - SST_dTdX = 0x0058, - SST_dWdX = 0x005c, - - SST_dRdY = 0x0060, - SST_dGdY = 0x0064, - SST_dBdY = 0x0068, - SST_dZdY = 0x006c, - SST_dAdY = 0x0070, - SST_dSdY = 0x0074, - SST_dTdY = 0x0078, - SST_dWdY = 0x007c, - - SST_triangleCMD = 0x0080, - - SST_fvertexAx = 0x088, - SST_fvertexAy = 0x08c, - SST_fvertexBx = 0x090, - SST_fvertexBy = 0x094, - SST_fvertexCx = 0x098, - SST_fvertexCy = 0x09c, - - SST_fstartR = 0x00a0, - SST_fstartG = 0x00a4, - SST_fstartB = 0x00a8, - SST_fstartZ = 0x00ac, - SST_fstartA = 0x00b0, - SST_fstartS = 0x00b4, - SST_fstartT = 0x00b8, - SST_fstartW = 0x00bc, - - SST_fdRdX = 0x00c0, - SST_fdGdX = 0x00c4, - SST_fdBdX = 0x00c8, - SST_fdZdX = 0x00cc, - SST_fdAdX = 0x00d0, - SST_fdSdX = 0x00d4, - SST_fdTdX = 0x00d8, - SST_fdWdX = 0x00dc, - - SST_fdRdY = 0x00e0, - SST_fdGdY = 0x00e4, - SST_fdBdY = 0x00e8, - SST_fdZdY = 0x00ec, - SST_fdAdY = 0x00f0, - SST_fdSdY = 0x00f4, - SST_fdTdY = 0x00f8, - SST_fdWdY = 0x00fc, - - SST_ftriangleCMD = 0x0100, - - SST_fbzColorPath = 0x104, - SST_fogMode = 0x108, - - SST_alphaMode = 0x10c, - SST_fbzMode = 0x110, - SST_lfbMode = 0x114, - - SST_clipLeftRight = 0x118, - SST_clipLowYHighY = 0x11c, - - SST_nopCMD = 0x120, - SST_fastfillCMD = 0x124, - SST_swapbufferCMD = 0x128, - - SST_fogColor = 0x12c, - SST_zaColor = 0x130, - SST_chromaKey = 0x134, - - SST_userIntrCMD = 0x13c, - SST_stipple = 0x140, - SST_color0 = 0x144, - SST_color1 = 0x148, - - SST_fbiPixelsIn = 0x14c, - SST_fbiChromaFail = 0x150, - SST_fbiZFuncFail = 0x154, - SST_fbiAFuncFail = 0x158, - SST_fbiPixelsOut = 0x15c, - - SST_fogTable00 = 0x160, - SST_fogTable01 = 0x164, - SST_fogTable02 = 0x168, - SST_fogTable03 = 0x16c, - SST_fogTable04 = 0x170, - SST_fogTable05 = 0x174, - SST_fogTable06 = 0x178, - SST_fogTable07 = 0x17c, - SST_fogTable08 = 0x180, - SST_fogTable09 = 0x184, - SST_fogTable0a = 0x188, - SST_fogTable0b = 0x18c, - SST_fogTable0c = 0x190, - SST_fogTable0d = 0x194, - SST_fogTable0e = 0x198, - SST_fogTable0f = 0x19c, - SST_fogTable10 = 0x1a0, - SST_fogTable11 = 0x1a4, - SST_fogTable12 = 0x1a8, - SST_fogTable13 = 0x1ac, - SST_fogTable14 = 0x1b0, - SST_fogTable15 = 0x1b4, - SST_fogTable16 = 0x1b8, - SST_fogTable17 = 0x1bc, - SST_fogTable18 = 0x1c0, - SST_fogTable19 = 0x1c4, - SST_fogTable1a = 0x1c8, - SST_fogTable1b = 0x1cc, - SST_fogTable1c = 0x1d0, - SST_fogTable1d = 0x1d4, - SST_fogTable1e = 0x1d8, - SST_fogTable1f = 0x1dc, - - SST_cmdFifoBaseAddr = 0x1e0, - SST_cmdFifoBump = 0x1e4, - SST_cmdFifoRdPtr = 0x1e8, - SST_cmdFifoAMin = 0x1ec, - SST_cmdFifoAMax = 0x1f0, - SST_cmdFifoDepth = 0x1f4, - SST_cmdFifoHoles = 0x1f8, - - SST_fbiInit4 = 0x200, - SST_vRetrace = 0x204, - SST_backPorch = 0x208, - SST_videoDimensions = 0x20c, - SST_fbiInit0 = 0x210, - SST_fbiInit1 = 0x214, - SST_fbiInit2 = 0x218, - SST_fbiInit3 = 0x21c, - SST_hSync = 0x220, - SST_vSync = 0x224, - SST_clutData = 0x228, - SST_dacData = 0x22c, - - SST_scrFilter = 0x230, - - SST_hvRetrace = 0x240, - SST_fbiInit5 = 0x244, - SST_fbiInit6 = 0x248, - SST_fbiInit7 = 0x24c, - - SST_sSetupMode = 0x260, - SST_sVx = 0x264, - SST_sVy = 0x268, - SST_sARGB = 0x26c, - SST_sRed = 0x270, - SST_sGreen = 0x274, - SST_sBlue = 0x278, - SST_sAlpha = 0x27c, - SST_sVz = 0x280, - SST_sWb = 0x284, - SST_sW0 = 0x288, - SST_sS0 = 0x28c, - SST_sT0 = 0x290, - SST_sW1 = 0x294, - SST_sS1 = 0x298, - SST_sT1 = 0x29c, - - SST_sDrawTriCMD = 0x2a0, - SST_sBeginTriCMD = 0x2a4, - - SST_bltSrcBaseAddr = 0x2c0, - SST_bltDstBaseAddr = 0x2c4, - SST_bltXYStrides = 0x2c8, - SST_bltSrcChromaRange = 0x2cc, - SST_bltDstChromaRange = 0x2d0, - SST_bltClipX = 0x2d4, - SST_bltClipY = 0x2d8, - - SST_bltSrcXY = 0x2e0, - SST_bltDstXY = 0x2e4, - SST_bltSize = 0x2e8, - SST_bltRop = 0x2ec, - SST_bltColor = 0x2f0, - - SST_bltCommand = 0x2f8, - SST_bltData = 0x2fc, - - SST_textureMode = 0x300, - SST_tLOD = 0x304, - SST_tDetail = 0x308, - SST_texBaseAddr = 0x30c, - SST_texBaseAddr1 = 0x310, - SST_texBaseAddr2 = 0x314, - SST_texBaseAddr38 = 0x318, - - SST_trexInit1 = 0x320, - - SST_nccTable0_Y0 = 0x324, - SST_nccTable0_Y1 = 0x328, - SST_nccTable0_Y2 = 0x32c, - SST_nccTable0_Y3 = 0x330, - SST_nccTable0_I0 = 0x334, - SST_nccTable0_I1 = 0x338, - SST_nccTable0_I2 = 0x33c, - SST_nccTable0_I3 = 0x340, - SST_nccTable0_Q0 = 0x344, - SST_nccTable0_Q1 = 0x348, - SST_nccTable0_Q2 = 0x34c, - SST_nccTable0_Q3 = 0x350, - - SST_nccTable1_Y0 = 0x354, - SST_nccTable1_Y1 = 0x358, - SST_nccTable1_Y2 = 0x35c, - SST_nccTable1_Y3 = 0x360, - SST_nccTable1_I0 = 0x364, - SST_nccTable1_I1 = 0x368, - SST_nccTable1_I2 = 0x36c, - SST_nccTable1_I3 = 0x370, - SST_nccTable1_Q0 = 0x374, - SST_nccTable1_Q1 = 0x378, - SST_nccTable1_Q2 = 0x37c, - SST_nccTable1_Q3 = 0x380, - - SST_remap_status = 0x000 | 0x400, - - SST_remap_vertexAx = 0x008 | 0x400, - SST_remap_vertexAy = 0x00c | 0x400, - SST_remap_vertexBx = 0x010 | 0x400, - SST_remap_vertexBy = 0x014 | 0x400, - SST_remap_vertexCx = 0x018 | 0x400, - SST_remap_vertexCy = 0x01c | 0x400, - - SST_remap_startR = 0x0020 | 0x400, - SST_remap_startG = 0x002c | 0x400, - SST_remap_startB = 0x0038 | 0x400, - SST_remap_startZ = 0x0044 | 0x400, - SST_remap_startA = 0x0050 | 0x400, - SST_remap_startS = 0x005c | 0x400, - SST_remap_startT = 0x0068 | 0x400, - SST_remap_startW = 0x0074 | 0x400, - - SST_remap_dRdX = 0x0024 | 0x400, - SST_remap_dGdX = 0x0030 | 0x400, - SST_remap_dBdX = 0x003c | 0x400, - SST_remap_dZdX = 0x0048 | 0x400, - SST_remap_dAdX = 0x0054 | 0x400, - SST_remap_dSdX = 0x0060 | 0x400, - SST_remap_dTdX = 0x006c | 0x400, - SST_remap_dWdX = 0x0078 | 0x400, - - SST_remap_dRdY = 0x0028 | 0x400, - SST_remap_dGdY = 0x0034 | 0x400, - SST_remap_dBdY = 0x0040 | 0x400, - SST_remap_dZdY = 0x004c | 0x400, - SST_remap_dAdY = 0x0058 | 0x400, - SST_remap_dSdY = 0x0064 | 0x400, - SST_remap_dTdY = 0x0070 | 0x400, - SST_remap_dWdY = 0x007c | 0x400, - - SST_remap_triangleCMD = 0x0080 | 0x400, - - SST_remap_fvertexAx = 0x088 | 0x400, - SST_remap_fvertexAy = 0x08c | 0x400, - SST_remap_fvertexBx = 0x090 | 0x400, - SST_remap_fvertexBy = 0x094 | 0x400, - SST_remap_fvertexCx = 0x098 | 0x400, - SST_remap_fvertexCy = 0x09c | 0x400, - - SST_remap_fstartR = 0x00a0 | 0x400, - SST_remap_fstartG = 0x00ac | 0x400, - SST_remap_fstartB = 0x00b8 | 0x400, - SST_remap_fstartZ = 0x00c4 | 0x400, - SST_remap_fstartA = 0x00d0 | 0x400, - SST_remap_fstartS = 0x00dc | 0x400, - SST_remap_fstartT = 0x00e8 | 0x400, - SST_remap_fstartW = 0x00f4 | 0x400, - - SST_remap_fdRdX = 0x00a4 | 0x400, - SST_remap_fdGdX = 0x00b0 | 0x400, - SST_remap_fdBdX = 0x00bc | 0x400, - SST_remap_fdZdX = 0x00c8 | 0x400, - SST_remap_fdAdX = 0x00d4 | 0x400, - SST_remap_fdSdX = 0x00e0 | 0x400, - SST_remap_fdTdX = 0x00ec | 0x400, - SST_remap_fdWdX = 0x00f8 | 0x400, - - SST_remap_fdRdY = 0x00a8 | 0x400, - SST_remap_fdGdY = 0x00b4 | 0x400, - SST_remap_fdBdY = 0x00c0 | 0x400, - SST_remap_fdZdY = 0x00cc | 0x400, - SST_remap_fdAdY = 0x00d8 | 0x400, - SST_remap_fdSdY = 0x00e4 | 0x400, - SST_remap_fdTdY = 0x00f0 | 0x400, - SST_remap_fdWdY = 0x00fc | 0x400, -}; - -enum -{ - LFB_WRITE_FRONT = 0x0000, - LFB_WRITE_BACK = 0x0010, - LFB_WRITE_MASK = 0x0030 -}; - -enum -{ - LFB_READ_FRONT = 0x0000, - LFB_READ_BACK = 0x0040, - LFB_READ_AUX = 0x0080, - LFB_READ_MASK = 0x00c0 -}; - -enum -{ - LFB_FORMAT_RGB565 = 0, - LFB_FORMAT_RGB555 = 1, - LFB_FORMAT_ARGB1555 = 2, - LFB_FORMAT_ARGB8888 = 5, - LFB_FORMAT_DEPTH = 15, - LFB_FORMAT_MASK = 15 -}; - -enum -{ - LFB_WRITE_COLOUR = 1, - LFB_WRITE_DEPTH = 2 -}; - -enum -{ - FBZ_CHROMAKEY = (1 << 1), - FBZ_W_BUFFER = (1 << 3), - FBZ_DEPTH_ENABLE = (1 << 4), - - FBZ_DITHER = (1 << 8), - FBZ_RGB_WMASK = (1 << 9), - FBZ_DEPTH_WMASK = (1 << 10), - FBZ_DITHER_2x2 = (1 << 11), - - FBZ_DRAW_FRONT = 0x0000, - FBZ_DRAW_BACK = 0x4000, - FBZ_DRAW_MASK = 0xc000, - - FBZ_DEPTH_BIAS = (1 << 16), - - FBZ_DEPTH_SOURCE = (1 << 20), - - FBZ_PARAM_ADJUST = (1 << 26) -}; - -enum -{ - TEX_RGB332 = 0x0, - TEX_Y4I2Q2 = 0x1, - TEX_A8 = 0x2, - TEX_I8 = 0x3, - TEX_AI8 = 0x4, - TEX_PAL8 = 0x5, - TEX_APAL8 = 0x6, - TEX_ARGB8332 = 0x8, - TEX_A8Y4I2Q2 = 0x9, - TEX_R5G6B5 = 0xa, - TEX_ARGB1555 = 0xb, - TEX_ARGB4444 = 0xc, - TEX_A8I8 = 0xd, - TEX_APAL88 = 0xe -}; - -enum -{ - TEXTUREMODE_NCC_SEL = (1 << 5), - TEXTUREMODE_TCLAMPS = (1 << 6), - TEXTUREMODE_TCLAMPT = (1 << 7), - TEXTUREMODE_TRILINEAR = (1 << 30) -}; - -enum -{ - FBIINIT0_VGA_PASS = 1, - FBIINIT0_GRAPHICS_RESET = (1 << 1) -}; - -enum -{ - FBIINIT1_MULTI_SST = (1 << 2), /*Voodoo Graphics only*/ - FBIINIT1_VIDEO_RESET = (1 << 8), - FBIINIT1_SLI_ENABLE = (1 << 23) -}; - -enum -{ - FBIINIT2_SWAP_ALGORITHM_MASK = (3 << 9) -}; - -enum -{ - FBIINIT2_SWAP_ALGORITHM_DAC_VSYNC = (0 << 9), - FBIINIT2_SWAP_ALGORITHM_DAC_DATA = (1 << 9), - FBIINIT2_SWAP_ALGORITHM_PCI_FIFO_STALL = (2 << 9), - FBIINIT2_SWAP_ALGORITHM_SLI_SYNC = (3 << 9) -}; - -enum -{ - FBIINIT3_REMAP = 1 -}; - -enum -{ - FBIINIT5_MULTI_CVG = (1 << 14) -}; - -enum -{ - FBIINIT7_CMDFIFO_ENABLE = (1 << 8) -}; - -enum -{ - CC_LOCALSELECT_ITER_RGB = 0, - CC_LOCALSELECT_TEX = 1, - CC_LOCALSELECT_COLOR1 = 2, - CC_LOCALSELECT_LFB = 3 -}; - -enum -{ - CCA_LOCALSELECT_ITER_A = 0, - CCA_LOCALSELECT_COLOR0 = 1, - CCA_LOCALSELECT_ITER_Z = 2 -}; - -enum -{ - C_SEL_ITER_RGB = 0, - C_SEL_TEX = 1, - C_SEL_COLOR1 = 2, - C_SEL_LFB = 3 -}; - -enum -{ - A_SEL_ITER_A = 0, - A_SEL_TEX = 1, - A_SEL_COLOR1 = 2, - A_SEL_LFB = 3 -}; - -enum -{ - CC_MSELECT_ZERO = 0, - CC_MSELECT_CLOCAL = 1, - CC_MSELECT_AOTHER = 2, - CC_MSELECT_ALOCAL = 3, - CC_MSELECT_TEX = 4, - CC_MSELECT_TEXRGB = 5 -}; - -enum -{ - CCA_MSELECT_ZERO = 0, - CCA_MSELECT_ALOCAL = 1, - CCA_MSELECT_AOTHER = 2, - CCA_MSELECT_ALOCAL2 = 3, - CCA_MSELECT_TEX = 4 -}; - -enum -{ - TC_MSELECT_ZERO = 0, - TC_MSELECT_CLOCAL = 1, - TC_MSELECT_AOTHER = 2, - TC_MSELECT_ALOCAL = 3, - TC_MSELECT_DETAIL = 4, - TC_MSELECT_LOD_FRAC = 5 -}; - -enum -{ - TCA_MSELECT_ZERO = 0, - TCA_MSELECT_CLOCAL = 1, - TCA_MSELECT_AOTHER = 2, - TCA_MSELECT_ALOCAL = 3, - TCA_MSELECT_DETAIL = 4, - TCA_MSELECT_LOD_FRAC = 5 -}; - -enum -{ - CC_ADD_CLOCAL = 1, - CC_ADD_ALOCAL = 2 -}; - -enum -{ - CCA_ADD_CLOCAL = 1, - CCA_ADD_ALOCAL = 2 -}; - -enum -{ - AFUNC_AZERO = 0x0, - AFUNC_ASRC_ALPHA = 0x1, - AFUNC_A_COLOR = 0x2, - AFUNC_ADST_ALPHA = 0x3, - AFUNC_AONE = 0x4, - AFUNC_AOMSRC_ALPHA = 0x5, - AFUNC_AOM_COLOR = 0x6, - AFUNC_AOMDST_ALPHA = 0x7, - AFUNC_ASATURATE = 0xf -}; - -enum -{ - AFUNC_ACOLORBEFOREFOG = 0xf -}; - -enum -{ - AFUNC_NEVER = 0, - AFUNC_LESSTHAN = 1, - AFUNC_EQUAL = 2, - AFUNC_LESSTHANEQUAL = 3, - AFUNC_GREATERTHAN = 4, - AFUNC_NOTEQUAL = 5, - AFUNC_GREATERTHANEQUAL = 6, - AFUNC_ALWAYS = 7 -}; - -enum -{ - DEPTHOP_NEVER = 0, - DEPTHOP_LESSTHAN = 1, - DEPTHOP_EQUAL = 2, - DEPTHOP_LESSTHANEQUAL = 3, - DEPTHOP_GREATERTHAN = 4, - DEPTHOP_NOTEQUAL = 5, - DEPTHOP_GREATERTHANEQUAL = 6, - DEPTHOP_ALWAYS = 7 -}; - -enum -{ - FOG_ENABLE = 0x01, - FOG_ADD = 0x02, - FOG_MULT = 0x04, - FOG_ALPHA = 0x08, - FOG_Z = 0x10, - FOG_W = 0x18, - FOG_CONSTANT = 0x20 -}; - -enum -{ - LOD_ODD = (1 << 18), - LOD_SPLIT = (1 << 19), - LOD_S_IS_WIDER = (1 << 20), - LOD_TMULTIBASEADDR = (1 << 24), - LOD_TMIRROR_S = (1 << 28), - LOD_TMIRROR_T = (1 << 29) -}; -enum -{ - CMD_INVALID = 0, - CMD_DRAWTRIANGLE, - CMD_FASTFILL, - CMD_SWAPBUF -}; - -enum -{ - FBZCP_TEXTURE_ENABLED = (1 << 27) -}; - -enum -{ - BLTCMD_SRC_TILED = (1 << 14), - BLTCMD_DST_TILED = (1 << 15) -}; - -enum -{ - INITENABLE_SLI_MASTER_SLAVE = (1 << 11) -}; - -#define TEXTUREMODE_MASK 0x3ffff000 -#define TEXTUREMODE_PASSTHROUGH 0 - -#define TEXTUREMODE_LOCAL_MASK 0x00643000 -#define TEXTUREMODE_LOCAL 0x00241000 - -#ifdef ENABLE_VOODOO_LOG -int voodoo_do_log = ENABLE_VOODOO_LOG; -#endif - - -static void -voodoo_log(const char *fmt, ...) -{ -#ifdef ENABLE_VOODOO_LOG - va_list ap; - - if (voodoo_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -static void voodoo_threshold_check(voodoo_t *voodoo); - -static void voodoo_update_ncc(voodoo_t *voodoo, int tmu) -{ - int tbl; - - for (tbl = 0; tbl < 2; tbl++) - { - int col; - - for (col = 0; col < 256; col++) - { - int y = (col >> 4), i = (col >> 2) & 3, q = col & 3; - int i_r, i_g, i_b; - int q_r, q_g, q_b; - - y = (voodoo->nccTable[tmu][tbl].y[y >> 2] >> ((y & 3) * 8)) & 0xff; - - i_r = (voodoo->nccTable[tmu][tbl].i[i] >> 18) & 0x1ff; - if (i_r & 0x100) - i_r |= 0xfffffe00; - i_g = (voodoo->nccTable[tmu][tbl].i[i] >> 9) & 0x1ff; - if (i_g & 0x100) - i_g |= 0xfffffe00; - i_b = voodoo->nccTable[tmu][tbl].i[i] & 0x1ff; - if (i_b & 0x100) - i_b |= 0xfffffe00; - - q_r = (voodoo->nccTable[tmu][tbl].q[q] >> 18) & 0x1ff; - if (q_r & 0x100) - q_r |= 0xfffffe00; - q_g = (voodoo->nccTable[tmu][tbl].q[q] >> 9) & 0x1ff; - if (q_g & 0x100) - q_g |= 0xfffffe00; - q_b = voodoo->nccTable[tmu][tbl].q[q] & 0x1ff; - if (q_b & 0x100) - q_b |= 0xfffffe00; - - voodoo->ncc_lookup[tmu][tbl][col].rgba.r = CLAMP(y + i_r + q_r); - voodoo->ncc_lookup[tmu][tbl][col].rgba.g = CLAMP(y + i_g + q_g); - voodoo->ncc_lookup[tmu][tbl][col].rgba.b = CLAMP(y + i_b + q_b); - voodoo->ncc_lookup[tmu][tbl][col].rgba.a = 0xff; - } - } -} - -#define SLI_ENABLED (voodoo->fbiInit1 & FBIINIT1_SLI_ENABLE) -#define TRIPLE_BUFFER ((voodoo->fbiInit2 & 0x10) || (voodoo->fbiInit5 & 0x600) == 0x400) -static void voodoo_recalc(voodoo_t *voodoo) -{ - uint32_t buffer_offset = ((voodoo->fbiInit2 >> 11) & 511) * 4096; - - voodoo->params.front_offset = voodoo->disp_buffer*buffer_offset; - voodoo->back_offset = voodoo->draw_buffer*buffer_offset; - - voodoo->buffer_cutoff = TRIPLE_BUFFER ? (buffer_offset * 4) : (buffer_offset * 3); - if (TRIPLE_BUFFER) - voodoo->params.aux_offset = buffer_offset * 3; - else - voodoo->params.aux_offset = buffer_offset * 2; - - switch (voodoo->lfbMode & LFB_WRITE_MASK) - { - case LFB_WRITE_FRONT: - voodoo->fb_write_offset = voodoo->params.front_offset; - voodoo->fb_write_buffer = voodoo->disp_buffer; - break; - case LFB_WRITE_BACK: - voodoo->fb_write_offset = voodoo->back_offset; - voodoo->fb_write_buffer = voodoo->draw_buffer; - break; - - default: - /*BreakNeck sets invalid LFB write buffer select*/ - voodoo->fb_write_offset = voodoo->params.front_offset; - break; - } - - switch (voodoo->lfbMode & LFB_READ_MASK) - { - case LFB_READ_FRONT: - voodoo->fb_read_offset = voodoo->params.front_offset; - break; - case LFB_READ_BACK: - voodoo->fb_read_offset = voodoo->back_offset; - break; - case LFB_READ_AUX: - voodoo->fb_read_offset = voodoo->params.aux_offset; - break; - - default: - fatal("voodoo_recalc : unknown lfb source\n"); - } - - switch (voodoo->params.fbzMode & FBZ_DRAW_MASK) - { - case FBZ_DRAW_FRONT: - voodoo->params.draw_offset = voodoo->params.front_offset; - voodoo->fb_draw_buffer = voodoo->disp_buffer; - break; - case FBZ_DRAW_BACK: - voodoo->params.draw_offset = voodoo->back_offset; - voodoo->fb_draw_buffer = voodoo->draw_buffer; - break; - - default: - fatal("voodoo_recalc : unknown draw buffer\n"); - } - - voodoo->block_width = ((voodoo->fbiInit1 >> 4) & 15) * 2; - if (voodoo->fbiInit6 & (1 << 30)) - voodoo->block_width += 1; - if (voodoo->fbiInit1 & (1 << 24)) - voodoo->block_width += 32; - voodoo->row_width = voodoo->block_width * 32 * 2; - -/* voodoo_log("voodoo_recalc : front_offset %08X back_offset %08X aux_offset %08X draw_offset %08x\n", voodoo->params.front_offset, voodoo->back_offset, voodoo->params.aux_offset, voodoo->params.draw_offset); - voodoo_log(" fb_read_offset %08X fb_write_offset %08X row_width %i %08x %08x\n", voodoo->fb_read_offset, voodoo->fb_write_offset, voodoo->row_width, voodoo->lfbMode, voodoo->params.fbzMode);*/ -} - -static void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) -{ - int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3; - int width = 256, height = 256; - int shift = 8; - int lod; - uint32_t base = voodoo->params.texBaseAddr[tmu]; - uint32_t offset = 0; - int tex_lod = 0; - - if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER) - height >>= aspect; - else - { - width >>= aspect; - shift -= aspect; - } - - if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD)) - { - width >>= 1; - height >>= 1; - shift--; - tex_lod++; - if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) - base = voodoo->params.texBaseAddr1[tmu]; - } - - for (lod = 0; lod <= LOD_MAX+1; lod++) - { - if (!width) - width = 1; - if (!height) - height = 1; - if (shift < 0) - shift = 0; - voodoo->params.tex_base[tmu][lod] = base + offset; - if (voodoo->params.tformat[tmu] & 8) - voodoo->params.tex_end[tmu][lod] = base + offset + (width * height * 2); - else - voodoo->params.tex_end[tmu][lod] = base + offset + (width * height); - voodoo->params.tex_w_mask[tmu][lod] = width - 1; - voodoo->params.tex_w_nmask[tmu][lod] = ~(width - 1); - voodoo->params.tex_h_mask[tmu][lod] = height - 1; - voodoo->params.tex_shift[tmu][lod] = shift; - voodoo->params.tex_lod[tmu][lod] = tex_lod; - - if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) || ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) - { - if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0) - { - if (voodoo->params.tformat[tmu] & 8) - offset += width * height * 2; - else - offset += width * height; - - if (voodoo->params.tLOD[tmu] & LOD_SPLIT) - { - width >>= 2; - height >>= 2; - shift -= 2; - tex_lod += 2; - } - else - { - width >>= 1; - height >>= 1; - shift--; - tex_lod++; - } - - if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) - { - switch (tex_lod) - { - case 0: - base = voodoo->params.texBaseAddr[tmu]; - break; - case 1: - base = voodoo->params.texBaseAddr1[tmu]; - break; - case 2: - base = voodoo->params.texBaseAddr2[tmu]; - break; - default: - base = voodoo->params.texBaseAddr38[tmu]; - break; - } - } - } - } - } - - voodoo->params.tex_width[tmu] = width; -} - -#define makergba(r, g, b, a) ((b) | ((g) << 8) | ((r) << 16) | ((a) << 24)) - -static void use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) -{ - int c, d; - int lod; - int lod_min, lod_max; - uint32_t addr = 0, addr_end; - uint32_t palette_checksum; - - lod_min = (params->tLOD[tmu] >> 2) & 15; - lod_max = (params->tLOD[tmu] >> 8) & 15; - - if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) - { - if (voodoo->palette_dirty[tmu]) - { - palette_checksum = 0; - - for (c = 0; c < 256; c++) - palette_checksum ^= voodoo->palette[tmu][c].u; - - voodoo->palette_checksum[tmu] = palette_checksum; - voodoo->palette_dirty[tmu] = 0; - } - else - palette_checksum = voodoo->palette_checksum[tmu]; - } - else - palette_checksum = 0; - - if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) - addr = params->texBaseAddr1[tmu]; - else - addr = params->texBaseAddr[tmu]; - - /*Try to find texture in cache*/ - for (c = 0; c < TEX_CACHE_MAX; c++) - { - if (voodoo->texture_cache[tmu][c].base == addr && - voodoo->texture_cache[tmu][c].tLOD == (params->tLOD[tmu] & 0xf00fff) && - voodoo->texture_cache[tmu][c].palette_checksum == palette_checksum) - { - params->tex_entry[tmu] = c; - voodoo->texture_cache[tmu][c].refcount++; - return; - } - } - - /*Texture not found, search for unused texture*/ - do - { - for (c = 0; c < TEX_CACHE_MAX; c++) - { - voodoo->texture_last_removed++; - voodoo->texture_last_removed &= (TEX_CACHE_MAX-1); - if (voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[0] && - (voodoo->render_threads == 1 || voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[1])) - break; - } - if (c == TEX_CACHE_MAX) - wait_for_render_thread_idle(voodoo); - } while (c == TEX_CACHE_MAX); - if (c == TEX_CACHE_MAX) - fatal("Texture cache full!\n"); - - c = voodoo->texture_last_removed; - - - if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) - voodoo->texture_cache[tmu][c].base = params->texBaseAddr1[tmu]; - else - voodoo->texture_cache[tmu][c].base = params->texBaseAddr[tmu]; - voodoo->texture_cache[tmu][c].tLOD = params->tLOD[tmu] & 0xf00fff; - - lod_min = (params->tLOD[tmu] >> 2) & 15; - lod_max = (params->tLOD[tmu] >> 8) & 15; -// voodoo_log(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu); - - lod_min = MIN(lod_min, 8); - lod_max = MIN(lod_max, 8); - for (lod = lod_min; lod <= lod_max; lod++) - { - uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]]; - uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask; - int x, y; - int shift = 8 - params->tex_lod[tmu][lod]; - rgba_u *pal; - - //voodoo_log(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]); - - - switch (params->tformat[tmu]) - { - case TEX_RGB332: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(rgb332[dat].r, rgb332[dat].g, rgb332[dat].b, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_Y4I2Q2: - pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_A8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(dat, dat, dat, dat); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_I8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(dat, dat, dat, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_AI8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba((dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0xf0) | ((dat >> 4) & 0x0f)); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_PAL8: - pal = voodoo->palette[tmu]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_APAL8: - pal = voodoo->palette[tmu]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - int r = ((pal[dat].rgba.r & 3) << 6) | ((pal[dat].rgba.g & 0xf0) >> 2) | (pal[dat].rgba.r & 3); - int g = ((pal[dat].rgba.g & 0xf) << 4) | ((pal[dat].rgba.b & 0xc0) >> 4) | ((pal[dat].rgba.g & 0xf) >> 2); - int b = ((pal[dat].rgba.b & 0x3f) << 2) | ((pal[dat].rgba.b & 0x30) >> 4); - int a = (pal[dat].rgba.r & 0xfc) | ((pal[dat].rgba.r & 0xc0) >> 6); - - base[x] = makergba(r, g, b, a); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_ARGB8332: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(rgb332[dat & 0xff].r, rgb332[dat & 0xff].g, rgb332[dat & 0xff].b, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_A8Y4I2Q2: - pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_R5G6B5: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(rgb565[dat].r, rgb565[dat].g, rgb565[dat].b, 0xff); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_ARGB1555: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(argb1555[dat].r, argb1555[dat].g, argb1555[dat].b, argb1555[dat].a); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_ARGB4444: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(argb4444[dat].r, argb4444[dat].g, argb4444[dat].b, argb4444[dat].a); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_A8I8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(dat & 0xff, dat & 0xff, dat & 0xff, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_APAL88: - pal = voodoo->palette[tmu]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - default: - fatal("Unknown texture format %i\n", params->tformat[tmu]); - } - } - - voodoo->texture_cache[tmu][c].is16 = voodoo->params.tformat[tmu] & 8; - - if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) - voodoo->texture_cache[tmu][c].palette_checksum = palette_checksum; - else - voodoo->texture_cache[tmu][c].palette_checksum = 0; - - if (lod_min == 0) - { - voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->params.tex_base[tmu][0]; - voodoo->texture_cache[tmu][c].addr_end[0] = voodoo->params.tex_end[tmu][0]; - } - else - voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->texture_cache[tmu][c].addr_end[0] = 0; - - if (lod_min <= 1 && lod_max >= 1) - { - voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->params.tex_base[tmu][1]; - voodoo->texture_cache[tmu][c].addr_end[1] = voodoo->params.tex_end[tmu][1]; - } - else - voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->texture_cache[tmu][c].addr_end[1] = 0; - - if (lod_min <= 2 && lod_max >= 2) - { - voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->params.tex_base[tmu][2]; - voodoo->texture_cache[tmu][c].addr_end[2] = voodoo->params.tex_end[tmu][2]; - } - else - voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->texture_cache[tmu][c].addr_end[2] = 0; - - if (lod_max >= 3) - { - voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->params.tex_base[tmu][(lod_min > 3) ? lod_min : 3]; - voodoo->texture_cache[tmu][c].addr_end[3] = voodoo->params.tex_end[tmu][(lod_max < 8) ? lod_max : 8]; - } - else - voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->texture_cache[tmu][c].addr_end[3] = 0; - - - for (d = 0; d < 4; d++) - { - addr = voodoo->texture_cache[tmu][c].addr_start[d]; - addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; - - if (addr_end != 0) - { - for (; addr <= addr_end; addr += (1 << TEX_DIRTY_SHIFT)) - voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; - } - } - - params->tex_entry[tmu] = c; - voodoo->texture_cache[tmu][c].refcount++; -} - -static void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) -{ - int wait_for_idle = 0; - int c; - - memset(voodoo->texture_present[tmu], 0, sizeof(voodoo->texture_present[0])); -// voodoo_log("Evict %08x %i\n", dirty_addr, sizeof(voodoo->texture_present)); - for (c = 0; c < TEX_CACHE_MAX; c++) - { - if (voodoo->texture_cache[tmu][c].base != -1) - { - int d; - - for (d = 0; d < 4; d++) - { - int addr_start = voodoo->texture_cache[tmu][c].addr_start[d]; - int addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; - - if (addr_end != 0) - { - int addr_start_masked = addr_start & voodoo->texture_mask & ~0x3ff; - int addr_end_masked = ((addr_end & voodoo->texture_mask) + 0x3ff) & ~0x3ff; - - if (addr_end_masked < addr_start_masked) - addr_end_masked = voodoo->texture_mask+1; - if (dirty_addr >= addr_start_masked && dirty_addr < addr_end_masked) - { -// voodoo_log(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base); - - if (voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[0] || - (voodoo->render_threads == 2 && voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[1])) - wait_for_idle = 1; - - voodoo->texture_cache[tmu][c].base = -1; - } - else - { - for (; addr_start <= addr_end; addr_start += (1 << TEX_DIRTY_SHIFT)) - voodoo->texture_present[tmu][(addr_start & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; - } - } - } - } - } - if (wait_for_idle) - wait_for_render_thread_idle(voodoo); -} - -typedef struct voodoo_state_t -{ - int xstart, xend, xdir; - uint32_t base_r, base_g, base_b, base_a, base_z; - struct - { - int64_t base_s, base_t, base_w; - int lod; - } tmu[2]; - int64_t base_w; - int lod; - int lod_min[2], lod_max[2]; - int dx1, dx2; - int y, yend, ydir; - int32_t dxAB, dxAC, dxBC; - int tex_b[2], tex_g[2], tex_r[2], tex_a[2]; - int tex_s, tex_t; - int clamp_s[2], clamp_t[2]; - - int32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy; - - uint32_t *tex[2][LOD_MAX+1]; - int tformat; - - int *tex_w_mask[2]; - int *tex_h_mask[2]; - int *tex_shift[2]; - int *tex_lod[2]; - - uint16_t *fb_mem, *aux_mem; - - int32_t ib, ig, ir, ia; - int32_t z; - - int32_t new_depth; - - int64_t tmu0_s, tmu0_t; - int64_t tmu0_w; - int64_t tmu1_s, tmu1_t; - int64_t tmu1_w; - int64_t w; - - int pixel_count, texel_count; - int x, x2; - - uint32_t w_depth; - - float log_temp; - uint32_t ebp_store; - uint32_t texBaseAddr; - - int lod_frac[2]; -} voodoo_state_t; - -static int voodoo_output = 0; - -static uint8_t logtable[256] = -{ - 0x00,0x01,0x02,0x04,0x05,0x07,0x08,0x09,0x0b,0x0c,0x0e,0x0f,0x10,0x12,0x13,0x15, - 0x16,0x17,0x19,0x1a,0x1b,0x1d,0x1e,0x1f,0x21,0x22,0x23,0x25,0x26,0x27,0x28,0x2a, - 0x2b,0x2c,0x2e,0x2f,0x30,0x31,0x33,0x34,0x35,0x36,0x38,0x39,0x3a,0x3b,0x3d,0x3e, - 0x3f,0x40,0x41,0x43,0x44,0x45,0x46,0x47,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x50,0x51, - 0x52,0x53,0x54,0x55,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x60,0x61,0x62,0x63, - 0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74, - 0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x81,0x83,0x84,0x85, - 0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94, - 0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,0xa0,0xa1,0xa2,0xa2,0xa3, - 0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xad,0xae,0xaf,0xb0,0xb1,0xb2, - 0xb3,0xb4,0xb5,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbc,0xbd,0xbe,0xbf,0xc0, - 0xc1,0xc2,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xcd, - 0xce,0xcf,0xd0,0xd1,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd6,0xd7,0xd8,0xd9,0xda,0xda, - 0xdb,0xdc,0xdd,0xde,0xde,0xdf,0xe0,0xe1,0xe1,0xe2,0xe3,0xe4,0xe5,0xe5,0xe6,0xe7, - 0xe8,0xe8,0xe9,0xea,0xeb,0xeb,0xec,0xed,0xee,0xef,0xef,0xf0,0xf1,0xf2,0xf2,0xf3, - 0xf4,0xf5,0xf5,0xf6,0xf7,0xf7,0xf8,0xf9,0xfa,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff -}; - -static inline int fastlog(uint64_t val) -{ - uint64_t oldval = val; - int exp = 63; - int frac; - - if (!val || val & (1ULL << 63)) - return 0x80000000; - - if (!(val & 0xffffffff00000000)) - { - exp -= 32; - val <<= 32; - } - if (!(val & 0xffff000000000000)) - { - exp -= 16; - val <<= 16; - } - if (!(val & 0xff00000000000000)) - { - exp -= 8; - val <<= 8; - } - if (!(val & 0xf000000000000000)) - { - exp -= 4; - val <<= 4; - } - if (!(val & 0xc000000000000000)) - { - exp -= 2; - val <<= 2; - } - if (!(val & 0x8000000000000000)) - { - exp -= 1; - val <<= 1; - } - - if (exp >= 8) - frac = (oldval >> (exp - 8)) & 0xff; - else - frac = (oldval << (8 - exp)) & 0xff; - - return (exp << 8) | logtable[frac]; -} - -static inline int voodoo_fls(uint16_t val) -{ - int num = 0; - -//voodoo_log("fls(%04x) = ", val); - if (!(val & 0xff00)) - { - num += 8; - val <<= 8; - } - if (!(val & 0xf000)) - { - num += 4; - val <<= 4; - } - if (!(val & 0xc000)) - { - num += 2; - val <<= 2; - } - if (!(val & 0x8000)) - { - num += 1; - val <<= 1; - } -//voodoo_log("%i %04x\n", num, val); - return num; -} - -typedef struct voodoo_texture_state_t -{ - int s, t; - int w_mask, h_mask; - int tex_shift; -} voodoo_texture_state_t; - -static inline void tex_read(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int tmu) -{ - uint32_t dat; - - if (texture_state->s & ~texture_state->w_mask) - { - if (state->clamp_s[tmu]) - { - if (texture_state->s < 0) - texture_state->s = 0; - if (texture_state->s > texture_state->w_mask) - texture_state->s = texture_state->w_mask; - } - else - texture_state->s &= texture_state->w_mask; - } - if (texture_state->t & ~texture_state->h_mask) - { - if (state->clamp_t[tmu]) - { - if (texture_state->t < 0) - texture_state->t = 0; - if (texture_state->t > texture_state->h_mask) - texture_state->t = texture_state->h_mask; - } - else - texture_state->t &= texture_state->h_mask; - } - - dat = state->tex[tmu][state->lod][texture_state->s + (texture_state->t << texture_state->tex_shift)]; - - state->tex_b[tmu] = dat & 0xff; - state->tex_g[tmu] = (dat >> 8) & 0xff; - state->tex_r[tmu] = (dat >> 16) & 0xff; - state->tex_a[tmu] = (dat >> 24) & 0xff; -} - -#define LOW4(x) ((x & 0x0f) | ((x & 0x0f) << 4)) -#define HIGH4(x) ((x & 0xf0) | ((x & 0xf0) >> 4)) - -static inline void tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int s, int t, int *d, int tmu, int x) -{ - rgba_u dat[4]; - - if (((s | (s + 1)) & ~texture_state->w_mask) || ((t | (t + 1)) & ~texture_state->h_mask)) - { - int c; - for (c = 0; c < 4; c++) - { - int _s = s + (c & 1); - int _t = t + ((c & 2) >> 1); - - if (_s & ~texture_state->w_mask) - { - if (state->clamp_s[tmu]) - { - if (_s < 0) - _s = 0; - if (_s > texture_state->w_mask) - _s = texture_state->w_mask; - } - else - _s &= texture_state->w_mask; - } - if (_t & ~texture_state->h_mask) - { - if (state->clamp_t[tmu]) - { - if (_t < 0) - _t = 0; - if (_t > texture_state->h_mask) - _t = texture_state->h_mask; - } - else - _t &= texture_state->h_mask; - } - dat[c].u = state->tex[tmu][state->lod][_s + (_t << texture_state->tex_shift)]; - } - } - else - { - dat[0].u = state->tex[tmu][state->lod][s + (t << texture_state->tex_shift)]; - dat[1].u = state->tex[tmu][state->lod][s + 1 + (t << texture_state->tex_shift)]; - dat[2].u = state->tex[tmu][state->lod][s + ((t + 1) << texture_state->tex_shift)]; - dat[3].u = state->tex[tmu][state->lod][s + 1 + ((t + 1) << texture_state->tex_shift)]; - } - - state->tex_r[tmu] = (dat[0].rgba.r * d[0] + dat[1].rgba.r * d[1] + dat[2].rgba.r * d[2] + dat[3].rgba.r * d[3]) >> 8; - state->tex_g[tmu] = (dat[0].rgba.g * d[0] + dat[1].rgba.g * d[1] + dat[2].rgba.g * d[2] + dat[3].rgba.g * d[3]) >> 8; - state->tex_b[tmu] = (dat[0].rgba.b * d[0] + dat[1].rgba.b * d[1] + dat[2].rgba.b * d[2] + dat[3].rgba.b * d[3]) >> 8; - state->tex_a[tmu] = (dat[0].rgba.a * d[0] + dat[1].rgba.a * d[1] + dat[2].rgba.a * d[2] + dat[3].rgba.a * d[3]) >> 8; -} - -static inline void voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) -{ - voodoo_texture_state_t texture_state; - int d[4]; - int s, t; - int tex_lod = state->tex_lod[tmu][state->lod]; - - texture_state.w_mask = state->tex_w_mask[tmu][state->lod]; - texture_state.h_mask = state->tex_h_mask[tmu][state->lod]; - texture_state.tex_shift = 8 - tex_lod; - - if (params->tLOD[tmu] & LOD_TMIRROR_S) - { - if (state->tex_s & 0x1000) - state->tex_s = ~state->tex_s; - } - if (params->tLOD[tmu] & LOD_TMIRROR_T) - { - if (state->tex_t & 0x1000) - state->tex_t = ~state->tex_t; - } - - if (voodoo->bilinear_enabled && params->textureMode[tmu] & 6) - { - int _ds, dt; - - state->tex_s -= 1 << (3+tex_lod); - state->tex_t -= 1 << (3+tex_lod); - - s = state->tex_s >> tex_lod; - t = state->tex_t >> tex_lod; - - _ds = s & 0xf; - dt = t & 0xf; - - s >>= 4; - t >>= 4; -//if (x == 80) -//if (voodoo_output) -// voodoo_log("s=%08x t=%08x _ds=%02x _dt=%02x\n", s, t, _ds, dt); - d[0] = (16 - _ds) * (16 - dt); - d[1] = _ds * (16 - dt); - d[2] = (16 - _ds) * dt; - d[3] = _ds * dt; - -// texture_state.s = s; -// texture_state.t = t; - tex_read_4(state, &texture_state, s, t, d, tmu, x); - - -/* state->tex_r = (tex_samples[0].rgba.r * d[0] + tex_samples[1].rgba.r * d[1] + tex_samples[2].rgba.r * d[2] + tex_samples[3].rgba.r * d[3]) >> 8; - state->tex_g = (tex_samples[0].rgba.g * d[0] + tex_samples[1].rgba.g * d[1] + tex_samples[2].rgba.g * d[2] + tex_samples[3].rgba.g * d[3]) >> 8; - state->tex_b = (tex_samples[0].rgba.b * d[0] + tex_samples[1].rgba.b * d[1] + tex_samples[2].rgba.b * d[2] + tex_samples[3].rgba.b * d[3]) >> 8; - state->tex_a = (tex_samples[0].rgba.a * d[0] + tex_samples[1].rgba.a * d[1] + tex_samples[2].rgba.a * d[2] + tex_samples[3].rgba.a * d[3]) >> 8;*/ -/* state->tex_r = tex_samples[0].r; - state->tex_g = tex_samples[0].g; - state->tex_b = tex_samples[0].b; - state->tex_a = tex_samples[0].a;*/ - } - else - { - // rgba_t tex_samples; - // voodoo_texture_state_t texture_state; -// int s = state->tex_s >> (18+state->lod); -// int t = state->tex_t >> (18+state->lod); - // int s, t; - -// state->tex_s -= 1 << (17+state->lod); -// state->tex_t -= 1 << (17+state->lod); - - s = state->tex_s >> (4+tex_lod); - t = state->tex_t >> (4+tex_lod); - - texture_state.s = s; - texture_state.t = t; - tex_read(state, &texture_state, tmu); - -/* state->tex_r = tex_samples[0].rgba.r; - state->tex_g = tex_samples[0].rgba.g; - state->tex_b = tex_samples[0].rgba.b; - state->tex_a = tex_samples[0].rgba.a;*/ - } -} - -static inline void voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) -{ - if (params->textureMode[tmu] & 1) - { - int64_t _w = 0; - - if (tmu) - { - if (state->tmu1_w) - _w = (int64_t)((1ULL << 48) / state->tmu1_w); - state->tex_s = (int32_t)(((((state->tmu1_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - state->tex_t = (int32_t)(((((state->tmu1_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - } - else - { - if (state->tmu0_w) - _w = (int64_t)((1ULL << 48) / state->tmu0_w); - state->tex_s = (int32_t)(((((state->tmu0_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - state->tex_t = (int32_t)(((((state->tmu0_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - } - - state->lod = state->tmu[tmu].lod + (fastlog(_w) - (19 << 8)); - } - else - { - if (tmu) - { - state->tex_s = (int32_t)(state->tmu1_s >> (14+14)); - state->tex_t = (int32_t)(state->tmu1_t >> (14+14)); - } - else - { - state->tex_s = (int32_t)(state->tmu0_s >> (14+14)); - state->tex_t = (int32_t)(state->tmu0_t >> (14+14)); - } - state->lod = state->tmu[tmu].lod; - } - - if (state->lod < state->lod_min[tmu]) - state->lod = state->lod_min[tmu]; - else if (state->lod > state->lod_max[tmu]) - state->lod = state->lod_max[tmu]; - state->lod_frac[tmu] = state->lod & 0xff; - state->lod >>= 8; - - voodoo_get_texture(voodoo, params, state, tmu, x); -} - -#define DEPTH_TEST(comp_depth) \ - do \ - { \ - switch (depth_op) \ - { \ - case DEPTHOP_NEVER: \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - case DEPTHOP_LESSTHAN: \ - if (!(comp_depth < old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_EQUAL: \ - if (!(comp_depth == old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_LESSTHANEQUAL: \ - if (!(comp_depth <= old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_GREATERTHAN: \ - if (!(comp_depth > old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_NOTEQUAL: \ - if (!(comp_depth != old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_GREATERTHANEQUAL: \ - if (!(comp_depth >= old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_ALWAYS: \ - break; \ - } \ - } while (0) - -#define APPLY_FOG(src_r, src_g, src_b, z, ia, w) \ - do \ - { \ - if (params->fogMode & FOG_CONSTANT) \ - { \ - src_r += params->fogColor.r; \ - src_g += params->fogColor.g; \ - src_b += params->fogColor.b; \ - } \ - else \ - { \ - int fog_r, fog_g, fog_b, fog_a = 0; \ - int fog_idx; \ - \ - if (!(params->fogMode & FOG_ADD)) \ - { \ - fog_r = params->fogColor.r; \ - fog_g = params->fogColor.g; \ - fog_b = params->fogColor.b; \ - } \ - else \ - fog_r = fog_g = fog_b = 0; \ - \ - if (!(params->fogMode & FOG_MULT)) \ - { \ - fog_r -= src_r; \ - fog_g -= src_g; \ - fog_b -= src_b; \ - } \ - \ - switch (params->fogMode & (FOG_Z|FOG_ALPHA)) \ - { \ - case 0: \ - fog_idx = (w_depth >> 10) & 0x3f; \ - \ - fog_a = params->fogTable[fog_idx].fog; \ - fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10; \ - break; \ - case FOG_Z: \ - fog_a = (z >> 20) & 0xff; \ - break; \ - case FOG_ALPHA: \ - fog_a = CLAMP(ia >> 12); \ - break; \ - case FOG_W: \ - fog_a = CLAMP((w >> 32) & 0xff); \ - break; \ - } \ - fog_a++; \ - \ - fog_r = (fog_r * fog_a) >> 8; \ - fog_g = (fog_g * fog_a) >> 8; \ - fog_b = (fog_b * fog_a) >> 8; \ - \ - if (params->fogMode & FOG_MULT) \ - { \ - src_r = fog_r; \ - src_g = fog_g; \ - src_b = fog_b; \ - } \ - else \ - { \ - src_r += fog_r; \ - src_g += fog_g; \ - src_b += fog_b; \ - } \ - } \ - \ - src_r = CLAMP(src_r); \ - src_g = CLAMP(src_g); \ - src_b = CLAMP(src_b); \ - } while (0) - -#define ALPHA_TEST(src_a) \ - do \ - { \ - switch (alpha_func) \ - { \ - case AFUNC_NEVER: \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - case AFUNC_LESSTHAN: \ - if (!(src_a < a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_EQUAL: \ - if (!(src_a == a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_LESSTHANEQUAL: \ - if (!(src_a <= a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_GREATERTHAN: \ - if (!(src_a > a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_NOTEQUAL: \ - if (!(src_a != a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_GREATERTHANEQUAL: \ - if (!(src_a >= a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_ALWAYS: \ - break; \ - } \ - } while (0) - -#define ALPHA_BLEND(src_r, src_g, src_b, src_a) \ - do \ - { \ - int _a; \ - int newdest_r = 0, newdest_g = 0, newdest_b = 0; \ - \ - switch (dest_afunc) \ - { \ - case AFUNC_AZERO: \ - newdest_r = newdest_g = newdest_b = 0; \ - break; \ - case AFUNC_ASRC_ALPHA: \ - newdest_r = (dest_r * src_a) / 255; \ - newdest_g = (dest_g * src_a) / 255; \ - newdest_b = (dest_b * src_a) / 255; \ - break; \ - case AFUNC_A_COLOR: \ - newdest_r = (dest_r * src_r) / 255; \ - newdest_g = (dest_g * src_g) / 255; \ - newdest_b = (dest_b * src_b) / 255; \ - break; \ - case AFUNC_ADST_ALPHA: \ - newdest_r = (dest_r * dest_a) / 255; \ - newdest_g = (dest_g * dest_a) / 255; \ - newdest_b = (dest_b * dest_a) / 255; \ - break; \ - case AFUNC_AONE: \ - newdest_r = dest_r; \ - newdest_g = dest_g; \ - newdest_b = dest_b; \ - break; \ - case AFUNC_AOMSRC_ALPHA: \ - newdest_r = (dest_r * (255-src_a)) / 255; \ - newdest_g = (dest_g * (255-src_a)) / 255; \ - newdest_b = (dest_b * (255-src_a)) / 255; \ - break; \ - case AFUNC_AOM_COLOR: \ - newdest_r = (dest_r * (255-src_r)) / 255; \ - newdest_g = (dest_g * (255-src_g)) / 255; \ - newdest_b = (dest_b * (255-src_b)) / 255; \ - break; \ - case AFUNC_AOMDST_ALPHA: \ - newdest_r = (dest_r * (255-dest_a)) / 255; \ - newdest_g = (dest_g * (255-dest_a)) / 255; \ - newdest_b = (dest_b * (255-dest_a)) / 255; \ - break; \ - case AFUNC_ASATURATE: \ - _a = MIN(src_a, 1-dest_a); \ - newdest_r = (dest_r * _a) / 255; \ - newdest_g = (dest_g * _a) / 255; \ - newdest_b = (dest_b * _a) / 255; \ - break; \ - } \ - \ - switch (src_afunc) \ - { \ - case AFUNC_AZERO: \ - src_r = src_g = src_b = 0; \ - break; \ - case AFUNC_ASRC_ALPHA: \ - src_r = (src_r * src_a) / 255; \ - src_g = (src_g * src_a) / 255; \ - src_b = (src_b * src_a) / 255; \ - break; \ - case AFUNC_A_COLOR: \ - src_r = (src_r * dest_r) / 255; \ - src_g = (src_g * dest_g) / 255; \ - src_b = (src_b * dest_b) / 255; \ - break; \ - case AFUNC_ADST_ALPHA: \ - src_r = (src_r * dest_a) / 255; \ - src_g = (src_g * dest_a) / 255; \ - src_b = (src_b * dest_a) / 255; \ - break; \ - case AFUNC_AONE: \ - break; \ - case AFUNC_AOMSRC_ALPHA: \ - src_r = (src_r * (255-src_a)) / 255; \ - src_g = (src_g * (255-src_a)) / 255; \ - src_b = (src_b * (255-src_a)) / 255; \ - break; \ - case AFUNC_AOM_COLOR: \ - src_r = (src_r * (255-dest_r)) / 255; \ - src_g = (src_g * (255-dest_g)) / 255; \ - src_b = (src_b * (255-dest_b)) / 255; \ - break; \ - case AFUNC_AOMDST_ALPHA: \ - src_r = (src_r * (255-dest_a)) / 255; \ - src_g = (src_g * (255-dest_a)) / 255; \ - src_b = (src_b * (255-dest_a)) / 255; \ - break; \ - case AFUNC_ACOLORBEFOREFOG: \ - fatal("AFUNC_ACOLORBEFOREFOG\n"); \ - break; \ - } \ - \ - src_r += newdest_r; \ - src_g += newdest_g; \ - src_b += newdest_b; \ - \ - src_r = CLAMP(src_r); \ - src_g = CLAMP(src_g); \ - src_b = CLAMP(src_b); \ - } while(0) - - -#define _rgb_sel ( params->fbzColorPath & 3) -#define a_sel ( (params->fbzColorPath >> 2) & 3) -#define cc_localselect ( params->fbzColorPath & (1 << 4)) -#define cca_localselect ( (params->fbzColorPath >> 5) & 3) -#define cc_localselect_override ( params->fbzColorPath & (1 << 7)) -#define cc_zero_other ( params->fbzColorPath & (1 << 8)) -#define cc_sub_clocal ( params->fbzColorPath & (1 << 9)) -#define cc_mselect ( (params->fbzColorPath >> 10) & 7) -#define cc_reverse_blend ( params->fbzColorPath & (1 << 13)) -#define cc_add ( (params->fbzColorPath >> 14) & 3) -#define cc_add_alocal ( params->fbzColorPath & (1 << 15)) -#define cc_invert_output ( params->fbzColorPath & (1 << 16)) -#define cca_zero_other ( params->fbzColorPath & (1 << 17)) -#define cca_sub_clocal ( params->fbzColorPath & (1 << 18)) -#define cca_mselect ( (params->fbzColorPath >> 19) & 7) -#define cca_reverse_blend ( params->fbzColorPath & (1 << 22)) -#define cca_add ( (params->fbzColorPath >> 23) & 3) -#define cca_invert_output ( params->fbzColorPath & (1 << 25)) -#define tc_zero_other (params->textureMode[0] & (1 << 12)) -#define tc_sub_clocal (params->textureMode[0] & (1 << 13)) -#define tc_mselect ((params->textureMode[0] >> 14) & 7) -#define tc_reverse_blend (params->textureMode[0] & (1 << 17)) -#define tc_add_clocal (params->textureMode[0] & (1 << 18)) -#define tc_add_alocal (params->textureMode[0] & (1 << 19)) -#define tc_invert_output (params->textureMode[0] & (1 << 20)) -#define tca_zero_other (params->textureMode[0] & (1 << 21)) -#define tca_sub_clocal (params->textureMode[0] & (1 << 22)) -#define tca_mselect ((params->textureMode[0] >> 23) & 7) -#define tca_reverse_blend (params->textureMode[0] & (1 << 26)) -#define tca_add_clocal (params->textureMode[0] & (1 << 27)) -#define tca_add_alocal (params->textureMode[0] & (1 << 28)) -#define tca_invert_output (params->textureMode[0] & (1 << 29)) - -#define tc_sub_clocal_1 (params->textureMode[1] & (1 << 13)) -#define tc_mselect_1 ((params->textureMode[1] >> 14) & 7) -#define tc_reverse_blend_1 (params->textureMode[1] & (1 << 17)) -#define tc_add_clocal_1 (params->textureMode[1] & (1 << 18)) -#define tc_add_alocal_1 (params->textureMode[1] & (1 << 19)) -#define tca_sub_clocal_1 (params->textureMode[1] & (1 << 22)) -#define tca_mselect_1 ((params->textureMode[1] >> 23) & 7) -#define tca_reverse_blend_1 (params->textureMode[1] & (1 << 26)) -#define tca_add_clocal_1 (params->textureMode[1] & (1 << 27)) -#define tca_add_alocal_1 (params->textureMode[1] & (1 << 28)) - -#define src_afunc ( (params->alphaMode >> 8) & 0xf) -#define dest_afunc ( (params->alphaMode >> 12) & 0xf) -#define alpha_func ( (params->alphaMode >> 1) & 7) -#define a_ref ( params->alphaMode >> 24) -#define depth_op ( (params->fbzMode >> 5) & 7) -#define dither ( params->fbzMode & FBZ_DITHER) -#define dither2x2 (params->fbzMode & FBZ_DITHER_2x2) - -/*Perform texture fetch and blending for both TMUs*/ -static inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) -{ - int r,g,b,a; - int c_reverse, a_reverse; -// int c_reverse1, a_reverse1; - int factor_r = 0, factor_g = 0, factor_b = 0, factor_a = 0; - - voodoo_tmu_fetch(voodoo, params, state, 1, x); - - if ((params->textureMode[1] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) - { - c_reverse = tc_reverse_blend; - a_reverse = tca_reverse_blend; - } - else - { - c_reverse = !tc_reverse_blend; - a_reverse = !tca_reverse_blend; - } -/* c_reverse1 = c_reverse; - a_reverse1 = a_reverse;*/ - if (tc_sub_clocal_1) - { - switch (tc_mselect_1) - { - case TC_MSELECT_ZERO: - factor_r = factor_g = factor_b = 0; - break; - case TC_MSELECT_CLOCAL: - factor_r = state->tex_r[1]; - factor_g = state->tex_g[1]; - factor_b = state->tex_b[1]; - break; - case TC_MSELECT_AOTHER: - factor_r = factor_g = factor_b = 0; - break; - case TC_MSELECT_ALOCAL: - factor_r = factor_g = factor_b = state->tex_a[1]; - break; - case TC_MSELECT_DETAIL: - factor_r = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; - if (factor_r > params->detail_max[1]) - factor_r = params->detail_max[1]; - factor_g = factor_b = factor_r; - break; - case TC_MSELECT_LOD_FRAC: - factor_r = factor_g = factor_b = state->lod_frac[1]; - break; - } - if (!c_reverse) - { - r = (-state->tex_r[1] * (factor_r + 1)) >> 8; - g = (-state->tex_g[1] * (factor_g + 1)) >> 8; - b = (-state->tex_b[1] * (factor_b + 1)) >> 8; - } - else - { - r = (-state->tex_r[1] * ((factor_r^0xff) + 1)) >> 8; - g = (-state->tex_g[1] * ((factor_g^0xff) + 1)) >> 8; - b = (-state->tex_b[1] * ((factor_b^0xff) + 1)) >> 8; - } - if (tc_add_clocal_1) - { - r += state->tex_r[1]; - g += state->tex_g[1]; - b += state->tex_b[1]; - } - else if (tc_add_alocal_1) - { - r += state->tex_a[1]; - g += state->tex_a[1]; - b += state->tex_a[1]; - } - state->tex_r[1] = CLAMP(r); - state->tex_g[1] = CLAMP(g); - state->tex_b[1] = CLAMP(b); - } - if (tca_sub_clocal_1) - { - switch (tca_mselect_1) - { - case TCA_MSELECT_ZERO: - factor_a = 0; - break; - case TCA_MSELECT_CLOCAL: - factor_a = state->tex_a[1]; - break; - case TCA_MSELECT_AOTHER: - factor_a = 0; - break; - case TCA_MSELECT_ALOCAL: - factor_a = state->tex_a[1]; - break; - case TCA_MSELECT_DETAIL: - factor_a = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; - if (factor_a > params->detail_max[1]) - factor_a = params->detail_max[1]; - break; - case TCA_MSELECT_LOD_FRAC: - factor_a = state->lod_frac[1]; - break; - } - if (!a_reverse) - a = (-state->tex_a[1] * ((factor_a ^ 0xff) + 1)) >> 8; - else - a = (-state->tex_a[1] * (factor_a + 1)) >> 8; - if (tca_add_clocal_1 || tca_add_alocal_1) - a += state->tex_a[1]; - state->tex_a[1] = CLAMP(a); - } - - - voodoo_tmu_fetch(voodoo, params, state, 0, x); - - if ((params->textureMode[0] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) - { - c_reverse = tc_reverse_blend; - a_reverse = tca_reverse_blend; - } - else - { - c_reverse = !tc_reverse_blend; - a_reverse = !tca_reverse_blend; - } - - if (!tc_zero_other) - { - r = state->tex_r[1]; - g = state->tex_g[1]; - b = state->tex_b[1]; - } - else - r = g = b = 0; - if (tc_sub_clocal) - { - r -= state->tex_r[0]; - g -= state->tex_g[0]; - b -= state->tex_b[0]; - } - switch (tc_mselect) - { - case TC_MSELECT_ZERO: - factor_r = factor_g = factor_b = 0; - break; - case TC_MSELECT_CLOCAL: - factor_r = state->tex_r[0]; - factor_g = state->tex_g[0]; - factor_b = state->tex_b[0]; - break; - case TC_MSELECT_AOTHER: - factor_r = factor_g = factor_b = state->tex_a[1]; - break; - case TC_MSELECT_ALOCAL: - factor_r = factor_g = factor_b = state->tex_a[0]; - break; - case TC_MSELECT_DETAIL: - factor_r = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; - if (factor_r > params->detail_max[0]) - factor_r = params->detail_max[0]; - factor_g = factor_b = factor_r; - break; - case TC_MSELECT_LOD_FRAC: - factor_r = factor_g = factor_b = state->lod_frac[0]; - break; - } - if (!c_reverse) - { - r = (r * (factor_r + 1)) >> 8; - g = (g * (factor_g + 1)) >> 8; - b = (b * (factor_b + 1)) >> 8; - } - else - { - r = (r * ((factor_r^0xff) + 1)) >> 8; - g = (g * ((factor_g^0xff) + 1)) >> 8; - b = (b * ((factor_b^0xff) + 1)) >> 8; - } - if (tc_add_clocal) - { - r += state->tex_r[0]; - g += state->tex_g[0]; - b += state->tex_b[0]; - } - else if (tc_add_alocal) - { - r += state->tex_a[0]; - g += state->tex_a[0]; - b += state->tex_a[0]; - } - - if (!tca_zero_other) - a = state->tex_a[1]; - else - a = 0; - if (tca_sub_clocal) - a -= state->tex_a[0]; - switch (tca_mselect) - { - case TCA_MSELECT_ZERO: - factor_a = 0; - break; - case TCA_MSELECT_CLOCAL: - factor_a = state->tex_a[0]; - break; - case TCA_MSELECT_AOTHER: - factor_a = state->tex_a[1]; - break; - case TCA_MSELECT_ALOCAL: - factor_a = state->tex_a[0]; - break; - case TCA_MSELECT_DETAIL: - factor_a = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; - if (factor_a > params->detail_max[0]) - factor_a = params->detail_max[0]; - break; - case TCA_MSELECT_LOD_FRAC: - factor_a = state->lod_frac[0]; - break; - } - if (a_reverse) - a = (a * ((factor_a ^ 0xff) + 1)) >> 8; - else - a = (a * (factor_a + 1)) >> 8; - if (tca_add_clocal || tca_add_alocal) - a += state->tex_a[0]; - - - state->tex_r[0] = CLAMP(r); - state->tex_g[0] = CLAMP(g); - state->tex_b[0] = CLAMP(b); - state->tex_a[0] = CLAMP(a); - - if (tc_invert_output) - { - state->tex_r[0] ^= 0xff; - state->tex_g[0] ^= 0xff; - state->tex_b[0] ^= 0xff; - } - if (tca_invert_output) - state->tex_a[0] ^= 0xff; -} - -#if ((defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32) && !(defined __amd64__) && (defined USE_DYNAREC)) -#include "vid_voodoo_codegen_x86.h" -#elif ((defined __amd64__) && (defined USE_DYNAREC)) -#include "vid_voodoo_codegen_x86-64.h" -#else -#define NO_CODEGEN -static int voodoo_recomp = 0; -#endif - -static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int ystart, int yend, int odd_even) -{ -/* int rgb_sel = params->fbzColorPath & 3; - int a_sel = (params->fbzColorPath >> 2) & 3; - int cc_localselect = params->fbzColorPath & (1 << 4); - int cca_localselect = (params->fbzColorPath >> 5) & 3; - int cc_localselect_override = params->fbzColorPath & (1 << 7); - int cc_zero_other = params->fbzColorPath & (1 << 8); - int cc_sub_clocal = params->fbzColorPath & (1 << 9); - int cc_mselect = (params->fbzColorPath >> 10) & 7; - int cc_reverse_blend = params->fbzColorPath & (1 << 13); - int cc_add = (params->fbzColorPath >> 14) & 3; - int cc_add_alocal = params->fbzColorPath & (1 << 15); - int cc_invert_output = params->fbzColorPath & (1 << 16); - int cca_zero_other = params->fbzColorPath & (1 << 17); - int cca_sub_clocal = params->fbzColorPath & (1 << 18); - int cca_mselect = (params->fbzColorPath >> 19) & 7; - int cca_reverse_blend = params->fbzColorPath & (1 << 22); - int cca_add = (params->fbzColorPath >> 23) & 3; - int cca_invert_output = params->fbzColorPath & (1 << 25); - int src_afunc = (params->alphaMode >> 8) & 0xf; - int dest_afunc = (params->alphaMode >> 12) & 0xf; - int alpha_func = (params->alphaMode >> 1) & 7; - int a_ref = params->alphaMode >> 24; - int depth_op = (params->fbzMode >> 5) & 7; - int dither = params->fbzMode & FBZ_DITHER;*/ - int texels; - int c; -#ifndef NO_CODEGEN - uint8_t (*voodoo_draw)(voodoo_state_t *state, voodoo_params_t *params, int x, int real_y); -#endif - uint8_t cother_r = 0, cother_g = 0, cother_b = 0; - int y_diff = SLI_ENABLED ? 2 : 1; - - if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || - (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) - texels = 1; - else - texels = 2; - - state->clamp_s[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPS; - state->clamp_t[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPT; - state->clamp_s[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPS; - state->clamp_t[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPT; -// int last_x; -// voodoo_log("voodoo_triangle : bottom-half %X %X %X %X %X %i %i %i %i\n", xstart, xend, dx1, dx2, dx2 * 36, xdir, y, yend, ydir); - - for (c = 0; c <= LOD_MAX; c++) - { - state->tex[0][c] = &voodoo->texture_cache[0][params->tex_entry[0]].data[texture_offset[c]]; - state->tex[1][c] = &voodoo->texture_cache[1][params->tex_entry[1]].data[texture_offset[c]]; - } - - state->tformat = params->tformat[0]; - - state->tex_w_mask[0] = params->tex_w_mask[0]; - state->tex_h_mask[0] = params->tex_h_mask[0]; - state->tex_shift[0] = params->tex_shift[0]; - state->tex_lod[0] = params->tex_lod[0]; - state->tex_w_mask[1] = params->tex_w_mask[1]; - state->tex_h_mask[1] = params->tex_h_mask[1]; - state->tex_shift[1] = params->tex_shift[1]; - state->tex_lod[1] = params->tex_lod[1]; - - if ((params->fbzMode & 1) && (ystart < params->clipLowY)) - { - int dy = params->clipLowY - ystart; - - state->base_r += params->dRdY*dy; - state->base_g += params->dGdY*dy; - state->base_b += params->dBdY*dy; - state->base_a += params->dAdY*dy; - state->base_z += params->dZdY*dy; - state->tmu[0].base_s += params->tmu[0].dSdY*dy; - state->tmu[0].base_t += params->tmu[0].dTdY*dy; - state->tmu[0].base_w += params->tmu[0].dWdY*dy; - state->tmu[1].base_s += params->tmu[1].dSdY*dy; - state->tmu[1].base_t += params->tmu[1].dTdY*dy; - state->tmu[1].base_w += params->tmu[1].dWdY*dy; - state->base_w += params->dWdY*dy; - state->xstart += state->dx1*dy; - state->xend += state->dx2*dy; - - ystart = params->clipLowY; - } - - if ((params->fbzMode & 1) && (yend >= params->clipHighY)) - yend = params->clipHighY-1; - - state->y = ystart; -// yend--; - - if (SLI_ENABLED) - { - int test_y; - - if (params->fbzMode & (1 << 17)) - test_y = (voodoo->v_disp-1) - state->y; - else - test_y = state->y; - - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (test_y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(test_y & 1))) - { - state->y++; - - state->base_r += params->dRdY; - state->base_g += params->dGdY; - state->base_b += params->dBdY; - state->base_a += params->dAdY; - state->base_z += params->dZdY; - state->tmu[0].base_s += params->tmu[0].dSdY; - state->tmu[0].base_t += params->tmu[0].dTdY; - state->tmu[0].base_w += params->tmu[0].dWdY; - state->tmu[1].base_s += params->tmu[1].dSdY; - state->tmu[1].base_t += params->tmu[1].dTdY; - state->tmu[1].base_w += params->tmu[1].dWdY; - state->base_w += params->dWdY; - state->xstart += state->dx1; - state->xend += state->dx2; - } - } -#ifndef NO_CODEGEN - if (voodoo->use_recompiler) - voodoo_draw = voodoo_get_block(voodoo, params, state, odd_even); - else - voodoo_draw = NULL; -#endif - - if (voodoo_output) - voodoo_log("dxAB=%08x dxBC=%08x dxAC=%08x\n", state->dxAB, state->dxBC, state->dxAC); -// voodoo_log("Start %i %i\n", ystart, voodoo->fbzMode & (1 << 17)); - - for (; state->y < yend; state->y += y_diff) - { - int x, x2; - int real_y = (state->y << 4) + 8; - int start_x, start_x2; - int dx; - uint16_t *fb_mem, *aux_mem; - - state->ir = state->base_r; - state->ig = state->base_g; - state->ib = state->base_b; - state->ia = state->base_a; - state->z = state->base_z; - state->tmu0_s = state->tmu[0].base_s; - state->tmu0_t = state->tmu[0].base_t; - state->tmu0_w = state->tmu[0].base_w; - state->tmu1_s = state->tmu[1].base_s; - state->tmu1_t = state->tmu[1].base_t; - state->tmu1_w = state->tmu[1].base_w; - state->w = state->base_w; - - x = (state->vertexAx << 12) + ((state->dxAC * (real_y - state->vertexAy)) >> 4); - - if (real_y < state->vertexBy) - x2 = (state->vertexAx << 12) + ((state->dxAB * (real_y - state->vertexAy)) >> 4); - else - x2 = (state->vertexBx << 12) + ((state->dxBC * (real_y - state->vertexBy)) >> 4); - - if (params->fbzMode & (1 << 17)) - real_y = (voodoo->v_disp-1) - (real_y >> 4); - else - real_y >>= 4; - - if (SLI_ENABLED) - { - if (((real_y >> 1) & voodoo->odd_even_mask) != odd_even) - goto next_line; - } - else - { - if ((real_y & voodoo->odd_even_mask) != odd_even) - goto next_line; - } - - start_x = x; - - if (state->xdir > 0) - x2 -= (1 << 16); - else - x -= (1 << 16); - dx = ((x + 0x7000) >> 16) - (((state->vertexAx << 12) + 0x7000) >> 16); - start_x2 = x + 0x7000; - x = (x + 0x7000) >> 16; - x2 = (x2 + 0x7000) >> 16; - - if (voodoo_output) - voodoo_log("%03i:%03i : Ax=%08x start_x=%08x dSdX=%016llx dx=%08x s=%08x -> ", x, state->y, state->vertexAx << 8, start_x, params->tmu[0].dTdX, dx, state->tmu0_t); - - state->ir += (params->dRdX * dx); - state->ig += (params->dGdX * dx); - state->ib += (params->dBdX * dx); - state->ia += (params->dAdX * dx); - state->z += (params->dZdX * dx); - state->tmu0_s += (params->tmu[0].dSdX * dx); - state->tmu0_t += (params->tmu[0].dTdX * dx); - state->tmu0_w += (params->tmu[0].dWdX * dx); - state->tmu1_s += (params->tmu[1].dSdX * dx); - state->tmu1_t += (params->tmu[1].dTdX * dx); - state->tmu1_w += (params->tmu[1].dWdX * dx); - state->w += (params->dWdX * dx); - - if (voodoo_output) - voodoo_log("%08llx %lli %lli\n", state->tmu0_t, state->tmu0_t >> (18+state->lod), (state->tmu0_t + (1 << (17+state->lod))) >> (18+state->lod)); - - if (params->fbzMode & 1) - { - if (state->xdir > 0) - { - if (x < params->clipLeft) - { - int dx = params->clipLeft - x; - - state->ir += params->dRdX*dx; - state->ig += params->dGdX*dx; - state->ib += params->dBdX*dx; - state->ia += params->dAdX*dx; - state->z += params->dZdX*dx; - state->tmu0_s += params->tmu[0].dSdX*dx; - state->tmu0_t += params->tmu[0].dTdX*dx; - state->tmu0_w += params->tmu[0].dWdX*dx; - state->tmu1_s += params->tmu[1].dSdX*dx; - state->tmu1_t += params->tmu[1].dTdX*dx; - state->tmu1_w += params->tmu[1].dWdX*dx; - state->w += params->dWdX*dx; - - x = params->clipLeft; - } - if (x2 >= params->clipRight) - x2 = params->clipRight-1; - } - else - { - if (x >= params->clipRight) - { - int dx = (params->clipRight-1) - x; - - state->ir += params->dRdX*dx; - state->ig += params->dGdX*dx; - state->ib += params->dBdX*dx; - state->ia += params->dAdX*dx; - state->z += params->dZdX*dx; - state->tmu0_s += params->tmu[0].dSdX*dx; - state->tmu0_t += params->tmu[0].dTdX*dx; - state->tmu0_w += params->tmu[0].dWdX*dx; - state->tmu1_s += params->tmu[1].dSdX*dx; - state->tmu1_t += params->tmu[1].dTdX*dx; - state->tmu1_w += params->tmu[1].dWdX*dx; - state->w += params->dWdX*dx; - - x = params->clipRight-1; - } - if (x2 < params->clipLeft) - x2 = params->clipLeft; - } - } - - if (x2 < x && state->xdir > 0) - goto next_line; - if (x2 > x && state->xdir < 0) - goto next_line; - - if (SLI_ENABLED) - { - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + ((real_y >> 1) * voodoo->row_width)]; - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + ((real_y >> 1) * voodoo->row_width)) & voodoo->fb_mask]; - } - else - { - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)]; - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask]; - } - - if (voodoo_output) - voodoo_log("%03i: x=%08x x2=%08x xstart=%08x xend=%08x dx=%08x start_x2=%08x\n", state->y, x, x2, state->xstart, state->xend, dx, start_x2); - - state->pixel_count = 0; - state->texel_count = 0; - state->x = x; - state->x2 = x2; -#ifndef NO_CODEGEN - if (voodoo->use_recompiler) - { - voodoo_draw(state, params, x, real_y); - } - else -#endif - do - { - start_x = x; - state->x = x; - voodoo->pixel_count[odd_even]++; - voodoo->texel_count[odd_even] += texels; - voodoo->fbiPixelsIn++; - - if (voodoo_output) - voodoo_log(" X=%03i T=%08x\n", x, state->tmu0_t); -// if (voodoo->fbzMode & FBZ_RGB_WMASK) - { - int update = 1; - uint8_t aother; - uint8_t clocal_r, clocal_g, clocal_b, alocal; - int src_r = 0, src_g = 0, src_b = 0, src_a = 0; - int msel_r, msel_g, msel_b, msel_a; - uint8_t dest_r, dest_g, dest_b, dest_a; - uint16_t dat; - int sel; - int32_t new_depth, w_depth; - - if (state->w & 0xffff00000000) - w_depth = 0; - else if (!(state->w & 0xffff0000)) - w_depth = 0xf001; - else - { - int exp = voodoo_fls((uint16_t)((uint32_t)state->w >> 16)); - int mant = ((~(uint32_t)state->w >> (19 - exp))) & 0xfff; - w_depth = (exp << 12) + mant + 1; - if (w_depth > 0xffff) - w_depth = 0xffff; - } - -// w_depth = CLAMP16(w_depth); - - if (params->fbzMode & FBZ_W_BUFFER) - new_depth = w_depth; - else - new_depth = CLAMP16(state->z >> 12); - - if (params->fbzMode & FBZ_DEPTH_BIAS) - new_depth = CLAMP16(new_depth + (int16_t)params->zaColor); - - if (params->fbzMode & FBZ_DEPTH_ENABLE) - { - uint16_t old_depth = aux_mem[x]; - - DEPTH_TEST((params->fbzMode & FBZ_DEPTH_SOURCE) ? (params->zaColor & 0xffff) : new_depth); - } - - dat = fb_mem[x]; - dest_r = (dat >> 8) & 0xf8; - dest_g = (dat >> 3) & 0xfc; - dest_b = (dat << 3) & 0xf8; - dest_r |= (dest_r >> 5); - dest_g |= (dest_g >> 6); - dest_b |= (dest_b >> 5); - dest_a = 0xff; - - if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) - { - if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || !voodoo->dual_tmus) - { - /*TMU0 only sampling local colour or only one TMU, only sample TMU0*/ - voodoo_tmu_fetch(voodoo, params, state, 0, x); - } - else if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH) - { - /*TMU0 in pass-through mode, only sample TMU1*/ - voodoo_tmu_fetch(voodoo, params, state, 1, x); - - state->tex_r[0] = state->tex_r[1]; - state->tex_g[0] = state->tex_g[1]; - state->tex_b[0] = state->tex_b[1]; - state->tex_a[0] = state->tex_a[1]; - } - else - { - voodoo_tmu_fetch_and_blend(voodoo, params, state, x); - } - - if ((params->fbzMode & FBZ_CHROMAKEY) && - state->tex_r[0] == params->chromaKey_r && - state->tex_g[0] == params->chromaKey_g && - state->tex_b[0] == params->chromaKey_b) - { - voodoo->fbiChromaFail++; - goto skip_pixel; - } - } - - if (voodoo->trexInit1[0] & (1 << 18)) - { - state->tex_r[0] = state->tex_g[0] = 0; - state->tex_b[0] = voodoo->tmuConfig; - } - - if (cc_localselect_override) - sel = (state->tex_a[0] & 0x80) ? 1 : 0; - else - sel = cc_localselect; - - if (sel) - { - clocal_r = (params->color0 >> 16) & 0xff; - clocal_g = (params->color0 >> 8) & 0xff; - clocal_b = params->color0 & 0xff; - } - else - { - clocal_r = CLAMP(state->ir >> 12); - clocal_g = CLAMP(state->ig >> 12); - clocal_b = CLAMP(state->ib >> 12); - } - - switch (_rgb_sel) - { - case CC_LOCALSELECT_ITER_RGB: /*Iterated RGB*/ - cother_r = CLAMP(state->ir >> 12); - cother_g = CLAMP(state->ig >> 12); - cother_b = CLAMP(state->ib >> 12); - break; - - case CC_LOCALSELECT_TEX: /*TREX Color Output*/ - cother_r = state->tex_r[0]; - cother_g = state->tex_g[0]; - cother_b = state->tex_b[0]; - break; - - case CC_LOCALSELECT_COLOR1: /*Color1 RGB*/ - cother_r = (params->color1 >> 16) & 0xff; - cother_g = (params->color1 >> 8) & 0xff; - cother_b = params->color1 & 0xff; - break; - - case CC_LOCALSELECT_LFB: /*Linear Frame Buffer*/ - cother_r = src_r; - cother_g = src_g; - cother_b = src_b; - break; - } - - switch (cca_localselect) - { - case CCA_LOCALSELECT_ITER_A: - alocal = CLAMP(state->ia >> 12); - break; - - case CCA_LOCALSELECT_COLOR0: - alocal = (params->color0 >> 24) & 0xff; - break; - - case CCA_LOCALSELECT_ITER_Z: - alocal = CLAMP(state->z >> 20); - break; - - default: - fatal("Bad cca_localselect %i\n", cca_localselect); - alocal = 0xff; - break; - } - - switch (a_sel) - { - case A_SEL_ITER_A: - aother = CLAMP(state->ia >> 12); - break; - case A_SEL_TEX: - aother = state->tex_a[0]; - break; - case A_SEL_COLOR1: - aother = (params->color1 >> 24) & 0xff; - break; - default: - fatal("Bad a_sel %i\n", a_sel); - aother = 0; - break; - } - - if (cc_zero_other) - { - src_r = 0; - src_g = 0; - src_b = 0; - } - else - { - src_r = cother_r; - src_g = cother_g; - src_b = cother_b; - } - - if (cca_zero_other) - src_a = 0; - else - src_a = aother; - - if (cc_sub_clocal) - { - src_r -= clocal_r; - src_g -= clocal_g; - src_b -= clocal_b; - } - - if (cca_sub_clocal) - src_a -= alocal; - - switch (cc_mselect) - { - case CC_MSELECT_ZERO: - msel_r = 0; - msel_g = 0; - msel_b = 0; - break; - case CC_MSELECT_CLOCAL: - msel_r = clocal_r; - msel_g = clocal_g; - msel_b = clocal_b; - break; - case CC_MSELECT_AOTHER: - msel_r = aother; - msel_g = aother; - msel_b = aother; - break; - case CC_MSELECT_ALOCAL: - msel_r = alocal; - msel_g = alocal; - msel_b = alocal; - break; - case CC_MSELECT_TEX: - msel_r = state->tex_a[0]; - msel_g = state->tex_a[0]; - msel_b = state->tex_a[0]; - break; - case CC_MSELECT_TEXRGB: - msel_r = state->tex_r[0]; - msel_g = state->tex_g[0]; - msel_b = state->tex_b[0]; - break; - - default: - fatal("Bad cc_mselect %i\n", cc_mselect); - msel_r = 0; - msel_g = 0; - msel_b = 0; - break; - } - - switch (cca_mselect) - { - case CCA_MSELECT_ZERO: - msel_a = 0; - break; - case CCA_MSELECT_ALOCAL: - msel_a = alocal; - break; - case CCA_MSELECT_AOTHER: - msel_a = aother; - break; - case CCA_MSELECT_ALOCAL2: - msel_a = alocal; - break; - case CCA_MSELECT_TEX: - msel_a = state->tex_a[0]; - break; - - default: - fatal("Bad cca_mselect %i\n", cca_mselect); - msel_a = 0; - break; - } - - if (!cc_reverse_blend) - { - msel_r ^= 0xff; - msel_g ^= 0xff; - msel_b ^= 0xff; - } - msel_r++; - msel_g++; - msel_b++; - - if (!cca_reverse_blend) - msel_a ^= 0xff; - msel_a++; - - src_r = (src_r * msel_r) >> 8; - src_g = (src_g * msel_g) >> 8; - src_b = (src_b * msel_b) >> 8; - src_a = (src_a * msel_a) >> 8; - - switch (cc_add) - { - case CC_ADD_CLOCAL: - src_r += clocal_r; - src_g += clocal_g; - src_b += clocal_b; - break; - case CC_ADD_ALOCAL: - src_r += alocal; - src_g += alocal; - src_b += alocal; - break; - case 0: - break; - default: - fatal("Bad cc_add %i\n", cc_add); - } - - if (cca_add) - src_a += alocal; - - src_r = CLAMP(src_r); - src_g = CLAMP(src_g); - src_b = CLAMP(src_b); - src_a = CLAMP(src_a); - - if (cc_invert_output) - { - src_r ^= 0xff; - src_g ^= 0xff; - src_b ^= 0xff; - } - if (cca_invert_output) - src_a ^= 0xff; - - if (params->fogMode & FOG_ENABLE) - APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w); - - if (params->alphaMode & 1) - ALPHA_TEST(src_a); - - if (params->alphaMode & (1 << 4)) - ALPHA_BLEND(src_r, src_g, src_b, src_a); - - if (update) - { - if (dither) - { - if (dither2x2) - { - src_r = dither_rb2x2[src_r][real_y & 1][x & 1]; - src_g = dither_g2x2[src_g][real_y & 1][x & 1]; - src_b = dither_rb2x2[src_b][real_y & 1][x & 1]; - } - else - { - src_r = dither_rb[src_r][real_y & 3][x & 3]; - src_g = dither_g[src_g][real_y & 3][x & 3]; - src_b = dither_rb[src_b][real_y & 3][x & 3]; - } - } - else - { - src_r >>= 3; - src_g >>= 2; - src_b >>= 3; - } - - if (params->fbzMode & FBZ_RGB_WMASK) - fb_mem[x] = src_b | (src_g << 5) | (src_r << 11); - - if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) - aux_mem[x] = new_depth; - } - } - voodoo_output &= ~2; - voodoo->fbiPixelsOut++; -skip_pixel: - if (state->xdir > 0) - { - state->ir += params->dRdX; - state->ig += params->dGdX; - state->ib += params->dBdX; - state->ia += params->dAdX; - state->z += params->dZdX; - state->tmu0_s += params->tmu[0].dSdX; - state->tmu0_t += params->tmu[0].dTdX; - state->tmu0_w += params->tmu[0].dWdX; - state->tmu1_s += params->tmu[1].dSdX; - state->tmu1_t += params->tmu[1].dTdX; - state->tmu1_w += params->tmu[1].dWdX; - state->w += params->dWdX; - } - else - { - state->ir -= params->dRdX; - state->ig -= params->dGdX; - state->ib -= params->dBdX; - state->ia -= params->dAdX; - state->z -= params->dZdX; - state->tmu0_s -= params->tmu[0].dSdX; - state->tmu0_t -= params->tmu[0].dTdX; - state->tmu0_w -= params->tmu[0].dWdX; - state->tmu1_s -= params->tmu[1].dSdX; - state->tmu1_t -= params->tmu[1].dTdX; - state->tmu1_w -= params->tmu[1].dWdX; - state->w -= params->dWdX; - } - - x += state->xdir; - } while (start_x != x2); - - voodoo->pixel_count[odd_even] += state->pixel_count; - voodoo->texel_count[odd_even] += state->texel_count; - voodoo->fbiPixelsIn += state->pixel_count; - - if (voodoo->params.draw_offset == voodoo->params.front_offset) - voodoo->dirty_line[real_y >> 1] = 1; -next_line: - if (SLI_ENABLED) - { - state->base_r += params->dRdY; - state->base_g += params->dGdY; - state->base_b += params->dBdY; - state->base_a += params->dAdY; - state->base_z += params->dZdY; - state->tmu[0].base_s += params->tmu[0].dSdY; - state->tmu[0].base_t += params->tmu[0].dTdY; - state->tmu[0].base_w += params->tmu[0].dWdY; - state->tmu[1].base_s += params->tmu[1].dSdY; - state->tmu[1].base_t += params->tmu[1].dTdY; - state->tmu[1].base_w += params->tmu[1].dWdY; - state->base_w += params->dWdY; - state->xstart += state->dx1; - state->xend += state->dx2; - } - state->base_r += params->dRdY; - state->base_g += params->dGdY; - state->base_b += params->dBdY; - state->base_a += params->dAdY; - state->base_z += params->dZdY; - state->tmu[0].base_s += params->tmu[0].dSdY; - state->tmu[0].base_t += params->tmu[0].dTdY; - state->tmu[0].base_w += params->tmu[0].dWdY; - state->tmu[1].base_s += params->tmu[1].dSdY; - state->tmu[1].base_t += params->tmu[1].dTdY; - state->tmu[1].base_w += params->tmu[1].dWdY; - state->base_w += params->dWdY; - state->xstart += state->dx1; - state->xend += state->dx2; - } - - voodoo->texture_cache[0][params->tex_entry[0]].refcount_r[odd_even]++; - voodoo->texture_cache[1][params->tex_entry[1]].refcount_r[odd_even]++; -} - -static void voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even) -{ - voodoo_state_t state; - int vertexAy_adjusted; - int vertexCy_adjusted; - int dx, dy; - - uint64_t tempdx, tempdy; - uint64_t tempLOD; - int LOD; - int lodbias; - - memset(&state, 0x00, sizeof(voodoo_state_t)); - voodoo->tri_count++; - - dx = 8 - (params->vertexAx & 0xf); - if ((params->vertexAx & 0xf) > 8) - dx += 16; - dy = 8 - (params->vertexAy & 0xf); - if ((params->vertexAy & 0xf) > 8) - dy += 16; - -/* voodoo_log("voodoo_triangle %i %i %i : vA %f, %f vB %f, %f vC %f, %f f %i,%i %08x %08x %08x,%08x tex=%i,%i fogMode=%08x\n", odd_even, voodoo->params_read_idx[odd_even], voodoo->params_read_idx[odd_even] & PARAM_MASK, (float)params->vertexAx / 16.0, (float)params->vertexAy / 16.0, - (float)params->vertexBx / 16.0, (float)params->vertexBy / 16.0, - (float)params->vertexCx / 16.0, (float)params->vertexCy / 16.0, - (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[0] : 0, - (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[1] : 0, params->fbzColorPath, params->alphaMode, params->textureMode[0],params->textureMode[1], params->tex_entry[0],params->tex_entry[1], params->fogMode);*/ - - state.base_r = params->startR; - state.base_g = params->startG; - state.base_b = params->startB; - state.base_a = params->startA; - state.base_z = params->startZ; - state.tmu[0].base_s = params->tmu[0].startS; - state.tmu[0].base_t = params->tmu[0].startT; - state.tmu[0].base_w = params->tmu[0].startW; - state.tmu[1].base_s = params->tmu[1].startS; - state.tmu[1].base_t = params->tmu[1].startT; - state.tmu[1].base_w = params->tmu[1].startW; - state.base_w = params->startW; - - if (params->fbzColorPath & FBZ_PARAM_ADJUST) - { - state.base_r += (dx*params->dRdX + dy*params->dRdY) >> 4; - state.base_g += (dx*params->dGdX + dy*params->dGdY) >> 4; - state.base_b += (dx*params->dBdX + dy*params->dBdY) >> 4; - state.base_a += (dx*params->dAdX + dy*params->dAdY) >> 4; - state.base_z += (dx*params->dZdX + dy*params->dZdY) >> 4; - state.tmu[0].base_s += (dx*params->tmu[0].dSdX + dy*params->tmu[0].dSdY) >> 4; - state.tmu[0].base_t += (dx*params->tmu[0].dTdX + dy*params->tmu[0].dTdY) >> 4; - state.tmu[0].base_w += (dx*params->tmu[0].dWdX + dy*params->tmu[0].dWdY) >> 4; - state.tmu[1].base_s += (dx*params->tmu[1].dSdX + dy*params->tmu[1].dSdY) >> 4; - state.tmu[1].base_t += (dx*params->tmu[1].dTdX + dy*params->tmu[1].dTdY) >> 4; - state.tmu[1].base_w += (dx*params->tmu[1].dWdX + dy*params->tmu[1].dWdY) >> 4; - state.base_w += (dx*params->dWdX + dy*params->dWdY) >> 4; - } - - tris++; - - state.vertexAy = params->vertexAy & ~0xffff0000; - if (state.vertexAy & 0x8000) - state.vertexAy |= 0xffff0000; - state.vertexBy = params->vertexBy & ~0xffff0000; - if (state.vertexBy & 0x8000) - state.vertexBy |= 0xffff0000; - state.vertexCy = params->vertexCy & ~0xffff0000; - if (state.vertexCy & 0x8000) - state.vertexCy |= 0xffff0000; - - state.vertexAx = params->vertexAx & ~0xffff0000; - if (state.vertexAx & 0x8000) - state.vertexAx |= 0xffff0000; - state.vertexBx = params->vertexBx & ~0xffff0000; - if (state.vertexBx & 0x8000) - state.vertexBx |= 0xffff0000; - state.vertexCx = params->vertexCx & ~0xffff0000; - if (state.vertexCx & 0x8000) - state.vertexCx |= 0xffff0000; - - vertexAy_adjusted = (state.vertexAy+7) >> 4; - vertexCy_adjusted = (state.vertexCy+7) >> 4; - - if (state.vertexBy - state.vertexAy) - state.dxAB = (int)((((int64_t)state.vertexBx << 12) - ((int64_t)state.vertexAx << 12)) << 4) / (int)(state.vertexBy - state.vertexAy); - else - state.dxAB = 0; - if (state.vertexCy - state.vertexAy) - state.dxAC = (int)((((int64_t)state.vertexCx << 12) - ((int64_t)state.vertexAx << 12)) << 4) / (int)(state.vertexCy - state.vertexAy); - else - state.dxAC = 0; - if (state.vertexCy - state.vertexBy) - state.dxBC = (int)((((int64_t)state.vertexCx << 12) - ((int64_t)state.vertexBx << 12)) << 4) / (int)(state.vertexCy - state.vertexBy); - else - state.dxBC = 0; - - state.lod_min[0] = (params->tLOD[0] & 0x3f) << 6; - state.lod_max[0] = ((params->tLOD[0] >> 6) & 0x3f) << 6; - if (state.lod_max[0] > 0x800) - state.lod_max[0] = 0x800; - state.lod_min[1] = (params->tLOD[1] & 0x3f) << 6; - state.lod_max[1] = ((params->tLOD[1] >> 6) & 0x3f) << 6; - if (state.lod_max[1] > 0x800) - state.lod_max[1] = 0x800; - - state.xstart = state.xend = state.vertexAx << 8; - state.xdir = params->sign ? -1 : 1; - - state.y = (state.vertexAy + 8) >> 4; - state.ydir = 1; - - - tempdx = (params->tmu[0].dSdX >> 14) * (params->tmu[0].dSdX >> 14) + (params->tmu[0].dTdX >> 14) * (params->tmu[0].dTdX >> 14); - tempdy = (params->tmu[0].dSdY >> 14) * (params->tmu[0].dSdY >> 14) + (params->tmu[0].dTdY >> 14) * (params->tmu[0].dTdY >> 14); - - if (tempdx > tempdy) - tempLOD = tempdx; - else - tempLOD = tempdy; - - LOD = (int)(log2((double)tempLOD / (double)(1ULL << 36)) * 256); - LOD >>= 2; - - lodbias = (params->tLOD[0] >> 12) & 0x3f; - if (lodbias & 0x20) - lodbias |= ~0x3f; - state.tmu[0].lod = LOD + (lodbias << 6); - - - tempdx = (params->tmu[1].dSdX >> 14) * (params->tmu[1].dSdX >> 14) + (params->tmu[1].dTdX >> 14) * (params->tmu[1].dTdX >> 14); - tempdy = (params->tmu[1].dSdY >> 14) * (params->tmu[1].dSdY >> 14) + (params->tmu[1].dTdY >> 14) * (params->tmu[1].dTdY >> 14); - - if (tempdx > tempdy) - tempLOD = tempdx; - else - tempLOD = tempdy; - - LOD = (int)(log2((double)tempLOD / (double)(1ULL << 36)) * 256); - LOD >>= 2; - - lodbias = (params->tLOD[1] >> 12) & 0x3f; - if (lodbias & 0x20) - lodbias |= ~0x3f; - state.tmu[1].lod = LOD + (lodbias << 6); - - - voodoo_half_triangle(voodoo, params, &state, vertexAy_adjusted, vertexCy_adjusted, odd_even); -} - -static inline void wake_render_thread(voodoo_t *voodoo) -{ - thread_set_event(voodoo->wake_render_thread[0]); /*Wake up render thread if moving from idle*/ - if (voodoo->render_threads == 2) - thread_set_event(voodoo->wake_render_thread[1]); /*Wake up render thread if moving from idle*/ -} - -static inline void wait_for_render_thread_idle(voodoo_t *voodoo) -{ - while (!PARAM_EMPTY_1 || (voodoo->render_threads == 2 && !PARAM_EMPTY_2) || voodoo->render_voodoo_busy[0] || (voodoo->render_threads == 2 && voodoo->render_voodoo_busy[1])) - { - wake_render_thread(voodoo); - if (!PARAM_EMPTY_1 || voodoo->render_voodoo_busy[0]) - thread_wait_event(voodoo->render_not_full_event[0], 1); - if (voodoo->render_threads == 2 && (!PARAM_EMPTY_2 || voodoo->render_voodoo_busy[1])) - thread_wait_event(voodoo->render_not_full_event[1], 1); - } -} - -static void render_thread(void *param, int odd_even) -{ - voodoo_t *voodoo = (voodoo_t *)param; - - while (1) - { - thread_set_event(voodoo->render_not_full_event[odd_even]); - thread_wait_event(voodoo->wake_render_thread[odd_even], -1); - thread_reset_event(voodoo->wake_render_thread[odd_even]); - voodoo->render_voodoo_busy[odd_even] = 1; - - while (!(odd_even ? PARAM_EMPTY_2 : PARAM_EMPTY_1)) - { - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - voodoo_params_t *params = &voodoo->params_buffer[voodoo->params_read_idx[odd_even] & PARAM_MASK]; - - voodoo_triangle(voodoo, params, odd_even); - - voodoo->params_read_idx[odd_even]++; - - if ((odd_even ? PARAM_ENTRIES_2 : PARAM_ENTRIES_1) > (PARAM_SIZE - 10)) - thread_set_event(voodoo->render_not_full_event[odd_even]); - - end_time = plat_timer_read(); - voodoo->render_time[odd_even] += end_time - start_time; - } - - voodoo->render_voodoo_busy[odd_even] = 0; - } -} - -static void render_thread_1(void *param) -{ - render_thread(param, 0); -} -static void render_thread_2(void *param) -{ - render_thread(param, 1); -} - -static inline void queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) -{ - voodoo_params_t *params_new = &voodoo->params_buffer[voodoo->params_write_idx & PARAM_MASK]; - - while (PARAM_FULL_1 || (voodoo->render_threads == 2 && PARAM_FULL_2)) - { - thread_reset_event(voodoo->render_not_full_event[0]); - if (voodoo->render_threads == 2) - thread_reset_event(voodoo->render_not_full_event[1]); - if (PARAM_FULL_1) - { - thread_wait_event(voodoo->render_not_full_event[0], -1); /*Wait for room in ringbuffer*/ - } - if (voodoo->render_threads == 2 && PARAM_FULL_2) - { - thread_wait_event(voodoo->render_not_full_event[1], -1); /*Wait for room in ringbuffer*/ - } - } - - use_texture(voodoo, params, 0); - if (voodoo->dual_tmus) - use_texture(voodoo, params, 1); - - memcpy(params_new, params, sizeof(voodoo_params_t)); - - voodoo->params_write_idx++; - - if (PARAM_ENTRIES_1 < 4 || (voodoo->render_threads == 2 && PARAM_ENTRIES_2 < 4)) - wake_render_thread(voodoo); -} - -static void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) -{ - int y; - int low_y, high_y; - - if (params->fbzMode & (1 << 17)) - { - high_y = voodoo->v_disp - params->clipLowY; - low_y = voodoo->v_disp - params->clipHighY; - } - else - { - low_y = params->clipLowY; - high_y = params->clipHighY; - } - - if (params->fbzMode & FBZ_RGB_WMASK) - { - int r, g, b; - uint16_t col; - - r = ((params->color1 >> 16) >> 3) & 0x1f; - g = ((params->color1 >> 8) >> 2) & 0x3f; - b = (params->color1 >> 3) & 0x1f; - col = b | (g << 5) | (r << 11); - - if (SLI_ENABLED) - { - for (y = low_y; y < high_y; y += 2) - { - uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; - int x; - - for (x = params->clipLeft; x < params->clipRight; x++) - cbuf[x] = col; - } - } - else - { - for (y = low_y; y < high_y; y++) - { - uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y*voodoo->row_width) & voodoo->fb_mask]; - int x; - - for (x = params->clipLeft; x < params->clipRight; x++) - cbuf[x] = col; - } - } - } - if (params->fbzMode & FBZ_DEPTH_WMASK) - { - if (SLI_ENABLED) - { - for (y = low_y; y < high_y; y += 2) - { - uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; - int x; - - for (x = params->clipLeft; x < params->clipRight; x++) - abuf[x] = params->zaColor & 0xffff; - } - } - else - { - for (y = low_y; y < high_y; y++) - { - uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y*voodoo->row_width) & voodoo->fb_mask]; - int x; - - for (x = params->clipLeft; x < params->clipRight; x++) - abuf[x] = params->zaColor & 0xffff; - } - } - } -} - -enum -{ - SETUPMODE_RGB = (1 << 0), - SETUPMODE_ALPHA = (1 << 1), - SETUPMODE_Z = (1 << 2), - SETUPMODE_Wb = (1 << 3), - SETUPMODE_W0 = (1 << 4), - SETUPMODE_S0_T0 = (1 << 5), - SETUPMODE_W1 = (1 << 6), - SETUPMODE_S1_T1 = (1 << 7), - - SETUPMODE_STRIP_MODE = (1 << 16), - SETUPMODE_CULLING_ENABLE = (1 << 17), - SETUPMODE_CULLING_SIGN = (1 << 18), - SETUPMODE_DISABLE_PINGPONG = (1 << 19) -}; - -static void triangle_setup(voodoo_t *voodoo) -{ - float dxAB, dxBC, dyAB, dyBC; - float area; - int va = 0, vb = 1, vc = 2; - int reverse_cull = 0; - - if (voodoo->verts[0].sVy < voodoo->verts[1].sVy) - { - if (voodoo->verts[1].sVy < voodoo->verts[2].sVy) - { - /* V1>V0, V2>V1, V2>V1>V0*/ - va = 0; /*OK*/ - vb = 1; - vc = 2; - } - else - { - /* V1>V0, V1>V2*/ - if (voodoo->verts[0].sVy < voodoo->verts[2].sVy) - { - /* V1>V0, V1>V2, V2>V0, V1>V2>V0*/ - va = 0; - vb = 2; - vc = 1; - reverse_cull = 1; - } - else - { - /* V1>V0, V1>V2, V0>V2, V1>V0>V2*/ - va = 2; - vb = 0; - vc = 1; - } - } - } - else - { - if (voodoo->verts[1].sVy < voodoo->verts[2].sVy) - { - /* V0>V1, V2>V1*/ - if (voodoo->verts[0].sVy < voodoo->verts[2].sVy) - { - /* V0>V1, V2>V1, V2>V0, V2>V0>V1*/ - va = 1; - vb = 0; - vc = 2; - reverse_cull = 1; - } - else - { - /* V0>V1, V2>V1, V0>V2, V0>V2>V1*/ - va = 1; - vb = 2; - vc = 0; - } - } - else - { - /*V0>V1>V2*/ - va = 2; - vb = 1; - vc = 0; - reverse_cull = 1; - } - } - - dxAB = voodoo->verts[va].sVx - voodoo->verts[vb].sVx; - dxBC = voodoo->verts[vb].sVx - voodoo->verts[vc].sVx; - dyAB = voodoo->verts[va].sVy - voodoo->verts[vb].sVy; - dyBC = voodoo->verts[vb].sVy - voodoo->verts[vc].sVy; - - area = dxAB * dyBC - dxBC * dyAB; - - if (area == 0.0) - { - if ((voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) && - !(voodoo->sSetupMode & SETUPMODE_DISABLE_PINGPONG)) - voodoo->sSetupMode ^= SETUPMODE_CULLING_SIGN; - - return; - } - - dxAB /= area; - dxBC /= area; - dyAB /= area; - dyBC /= area; - - if (voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) - { - int cull_sign = voodoo->sSetupMode & SETUPMODE_CULLING_SIGN; - int sign = (area < 0.0); - - if (!(voodoo->sSetupMode & SETUPMODE_DISABLE_PINGPONG)) - voodoo->sSetupMode ^= SETUPMODE_CULLING_SIGN; - - if (reverse_cull) - sign = !sign; - - if (cull_sign && sign) - return; - if (!cull_sign && !sign) - return; - } - - voodoo->params.vertexAx = (int32_t)(int16_t)((int32_t)(voodoo->verts[va].sVx * 16.0f) & 0xffff); - voodoo->params.vertexAy = (int32_t)(int16_t)((int32_t)(voodoo->verts[va].sVy * 16.0f) & 0xffff); - voodoo->params.vertexBx = (int32_t)(int16_t)((int32_t)(voodoo->verts[vb].sVx * 16.0f) & 0xffff); - voodoo->params.vertexBy = (int32_t)(int16_t)((int32_t)(voodoo->verts[vb].sVy * 16.0f) & 0xffff); - voodoo->params.vertexCx = (int32_t)(int16_t)((int32_t)(voodoo->verts[vc].sVx * 16.0f) & 0xffff); - voodoo->params.vertexCy = (int32_t)(int16_t)((int32_t)(voodoo->verts[vc].sVy * 16.0f) & 0xffff); - - if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy) - fatal("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy); - - if (voodoo->sSetupMode & SETUPMODE_RGB) - { - voodoo->params.startR = (int32_t)(voodoo->verts[va].sRed * 4096.0f); - voodoo->params.dRdX = (int32_t)(((voodoo->verts[va].sRed - voodoo->verts[vb].sRed) * dyBC - (voodoo->verts[vb].sRed - voodoo->verts[vc].sRed) * dyAB) * 4096.0f); - voodoo->params.dRdY = (int32_t)(((voodoo->verts[vb].sRed - voodoo->verts[vc].sRed) * dxAB - (voodoo->verts[va].sRed - voodoo->verts[vb].sRed) * dxBC) * 4096.0f); - voodoo->params.startG = (int32_t)(voodoo->verts[va].sGreen * 4096.0f); - voodoo->params.dGdX = (int32_t)(((voodoo->verts[va].sGreen - voodoo->verts[vb].sGreen) * dyBC - (voodoo->verts[vb].sGreen - voodoo->verts[vc].sGreen) * dyAB) * 4096.0f); - voodoo->params.dGdY = (int32_t)(((voodoo->verts[vb].sGreen - voodoo->verts[vc].sGreen) * dxAB - (voodoo->verts[va].sGreen - voodoo->verts[vb].sGreen) * dxBC) * 4096.0f); - voodoo->params.startB = (int32_t)(voodoo->verts[va].sBlue * 4096.0f); - voodoo->params.dBdX = (int32_t)(((voodoo->verts[va].sBlue - voodoo->verts[vb].sBlue) * dyBC - (voodoo->verts[vb].sBlue - voodoo->verts[vc].sBlue) * dyAB) * 4096.0f); - voodoo->params.dBdY = (int32_t)(((voodoo->verts[vb].sBlue - voodoo->verts[vc].sBlue) * dxAB - (voodoo->verts[va].sBlue - voodoo->verts[vb].sBlue) * dxBC) * 4096.0f); - } - if (voodoo->sSetupMode & SETUPMODE_ALPHA) - { - voodoo->params.startA = (int32_t)(voodoo->verts[va].sAlpha * 4096.0f); - voodoo->params.dAdX = (int32_t)(((voodoo->verts[va].sAlpha - voodoo->verts[vb].sAlpha) * dyBC - (voodoo->verts[vb].sAlpha - voodoo->verts[vc].sAlpha) * dyAB) * 4096.0f); - voodoo->params.dAdY = (int32_t)(((voodoo->verts[vb].sAlpha - voodoo->verts[vc].sAlpha) * dxAB - (voodoo->verts[va].sAlpha - voodoo->verts[vb].sAlpha) * dxBC) * 4096.0f); - } - if (voodoo->sSetupMode & SETUPMODE_Z) - { - voodoo->params.startZ = (int32_t)(voodoo->verts[va].sVz * 4096.0f); - voodoo->params.dZdX = (int32_t)(((voodoo->verts[va].sVz - voodoo->verts[vb].sVz) * dyBC - (voodoo->verts[vb].sVz - voodoo->verts[vc].sVz) * dyAB) * 4096.0f); - voodoo->params.dZdY = (int32_t)(((voodoo->verts[vb].sVz - voodoo->verts[vc].sVz) * dxAB - (voodoo->verts[va].sVz - voodoo->verts[vb].sVz) * dxBC) * 4096.0f); - } - if (voodoo->sSetupMode & SETUPMODE_Wb) - { - voodoo->params.startW = (int64_t)(voodoo->verts[va].sWb * 4294967296.0f); - voodoo->params.dWdX = (int64_t)(((voodoo->verts[va].sWb - voodoo->verts[vb].sWb) * dyBC - (voodoo->verts[vb].sWb - voodoo->verts[vc].sWb) * dyAB) * 4294967296.0f); - voodoo->params.dWdY = (int64_t)(((voodoo->verts[vb].sWb - voodoo->verts[vc].sWb) * dxAB - (voodoo->verts[va].sWb - voodoo->verts[vb].sWb) * dxBC) * 4294967296.0f); - voodoo->params.tmu[0].startW = voodoo->params.tmu[1].startW = voodoo->params.startW; - voodoo->params.tmu[0].dWdX = voodoo->params.tmu[1].dWdX = voodoo->params.dWdX; - voodoo->params.tmu[0].dWdY = voodoo->params.tmu[1].dWdY = voodoo->params.dWdY; - } - if (voodoo->sSetupMode & SETUPMODE_W0) - { - voodoo->params.tmu[0].startW = (int64_t)(voodoo->verts[va].sW0 * 4294967296.0f); - voodoo->params.tmu[0].dWdX = (int64_t)(((voodoo->verts[va].sW0 - voodoo->verts[vb].sW0) * dyBC - (voodoo->verts[vb].sW0 - voodoo->verts[vc].sW0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dWdY = (int64_t)(((voodoo->verts[vb].sW0 - voodoo->verts[vc].sW0) * dxAB - (voodoo->verts[va].sW0 - voodoo->verts[vb].sW0) * dxBC) * 4294967296.0f); - voodoo->params.tmu[1].startW = voodoo->params.tmu[0].startW; - voodoo->params.tmu[1].dWdX = voodoo->params.tmu[0].dWdX; - voodoo->params.tmu[1].dWdY = voodoo->params.tmu[0].dWdY; - } - if (voodoo->sSetupMode & SETUPMODE_S0_T0) - { - voodoo->params.tmu[0].startS = (int64_t)(voodoo->verts[va].sS0 * 4294967296.0f); - voodoo->params.tmu[0].dSdX = (int64_t)(((voodoo->verts[va].sS0 - voodoo->verts[vb].sS0) * dyBC - (voodoo->verts[vb].sS0 - voodoo->verts[vc].sS0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dSdY = (int64_t)(((voodoo->verts[vb].sS0 - voodoo->verts[vc].sS0) * dxAB - (voodoo->verts[va].sS0 - voodoo->verts[vb].sS0) * dxBC) * 4294967296.0f); - voodoo->params.tmu[0].startT = (int64_t)(voodoo->verts[va].sT0 * 4294967296.0f); - voodoo->params.tmu[0].dTdX = (int64_t)(((voodoo->verts[va].sT0 - voodoo->verts[vb].sT0) * dyBC - (voodoo->verts[vb].sT0 - voodoo->verts[vc].sT0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dTdY = (int64_t)(((voodoo->verts[vb].sT0 - voodoo->verts[vc].sT0) * dxAB - (voodoo->verts[va].sT0 - voodoo->verts[vb].sT0) * dxBC) * 4294967296.0f); - voodoo->params.tmu[1].startS = voodoo->params.tmu[0].startS; - voodoo->params.tmu[1].dSdX = voodoo->params.tmu[0].dSdX; - voodoo->params.tmu[1].dSdY = voodoo->params.tmu[0].dSdY; - voodoo->params.tmu[1].startT = voodoo->params.tmu[0].startT; - voodoo->params.tmu[1].dTdX = voodoo->params.tmu[0].dTdX; - voodoo->params.tmu[1].dTdY = voodoo->params.tmu[0].dTdY; - } - if (voodoo->sSetupMode & SETUPMODE_W1) - { - voodoo->params.tmu[1].startW = (int64_t)(voodoo->verts[va].sW1 * 4294967296.0f); - voodoo->params.tmu[1].dWdX = (int64_t)(((voodoo->verts[va].sW1 - voodoo->verts[vb].sW1) * dyBC - (voodoo->verts[vb].sW1 - voodoo->verts[vc].sW1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dWdY = (int64_t)(((voodoo->verts[vb].sW1 - voodoo->verts[vc].sW1) * dxAB - (voodoo->verts[va].sW1 - voodoo->verts[vb].sW1) * dxBC) * 4294967296.0f); - } - if (voodoo->sSetupMode & SETUPMODE_S1_T1) - { - voodoo->params.tmu[1].startS = (int64_t)(voodoo->verts[va].sS1 * 4294967296.0f); - voodoo->params.tmu[1].dSdX = (int64_t)(((voodoo->verts[va].sS1 - voodoo->verts[vb].sS1) * dyBC - (voodoo->verts[vb].sS1 - voodoo->verts[vc].sS1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dSdY = (int64_t)(((voodoo->verts[vb].sS1 - voodoo->verts[vc].sS1) * dxAB - (voodoo->verts[va].sS1 - voodoo->verts[vb].sS1) * dxBC) * 4294967296.0f); - voodoo->params.tmu[1].startT = (int64_t)(voodoo->verts[va].sT1 * 4294967296.0f); - voodoo->params.tmu[1].dTdX = (int64_t)(((voodoo->verts[va].sT1 - voodoo->verts[vb].sT1) * dyBC - (voodoo->verts[vb].sT1 - voodoo->verts[vc].sT1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dTdY = (int64_t)(((voodoo->verts[vb].sT1 - voodoo->verts[vc].sT1) * dxAB - (voodoo->verts[va].sT1 - voodoo->verts[vb].sT1) * dxBC) * 4294967296.0f); - } - - voodoo->params.sign = (area < 0.0); - - if (voodoo->ncc_dirty[0]) - voodoo_update_ncc(voodoo, 0); - if (voodoo->ncc_dirty[1]) - voodoo_update_ncc(voodoo, 1); - voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; - - queue_triangle(voodoo, &voodoo->params); -} - -enum -{ - BLIT_COMMAND_SCREEN_TO_SCREEN = 0, - BLIT_COMMAND_CPU_TO_SCREEN = 1, - BLIT_COMMAND_RECT_FILL = 2, - BLIT_COMMAND_SGRAM_FILL = 3 -}; - -enum -{ - BLIT_SRC_1BPP = (0 << 3), - BLIT_SRC_1BPP_BYTE_PACKED = (1 << 3), - BLIT_SRC_16BPP = (2 << 3), - BLIT_SRC_24BPP = (3 << 3), - BLIT_SRC_24BPP_DITHER_2X2 = (4 << 3), - BLIT_SRC_24BPP_DITHER_4X4 = (5 << 3) -}; - -enum -{ - BLIT_SRC_RGB_ARGB = (0 << 6), - BLIT_SRC_RGB_ABGR = (1 << 6), - BLIT_SRC_RGB_RGBA = (2 << 6), - BLIT_SRC_RGB_BGRA = (3 << 6) -}; - -enum -{ - BLIT_COMMAND_MASK = 7, - BLIT_SRC_FORMAT = (7 << 3), - BLIT_SRC_RGB_FORMAT = (3 << 6), - BLIT_SRC_CHROMA = (1 << 10), - BLIT_DST_CHROMA = (1 << 12), - BLIT_CLIPPING_ENABLED = (1 << 16) -}; - -enum -{ - BLIT_ROP_DST_PASS = (1 << 0), - BLIT_ROP_SRC_PASS = (1 << 1) -}; - -#define MIX(src_dat, dst_dat, rop) \ - switch (rop) \ - { \ - case 0x0: dst_dat = 0; break; \ - case 0x1: dst_dat = ~(src_dat | dst_dat); break; \ - case 0x2: dst_dat = ~src_dat & dst_dat; break; \ - case 0x3: dst_dat = ~src_dat; break; \ - case 0x4: dst_dat = src_dat & ~dst_dat; break; \ - case 0x5: dst_dat = ~dst_dat; break; \ - case 0x6: dst_dat = src_dat ^ dst_dat; break; \ - case 0x7: dst_dat = ~(src_dat & dst_dat); break; \ - case 0x8: dst_dat = src_dat & dst_dat; break; \ - case 0x9: dst_dat = ~(src_dat ^ dst_dat); break; \ - case 0xa: dst_dat = dst_dat; break; \ - case 0xb: dst_dat = ~src_dat | dst_dat; break; \ - case 0xc: dst_dat = src_dat; break; \ - case 0xd: dst_dat = src_dat | ~dst_dat; break; \ - case 0xe: dst_dat = src_dat | dst_dat; break; \ - case 0xf: dst_dat = 0xffff; break; \ - } - -static void blit_start(voodoo_t *voodoo) -{ - uint64_t dat64; - int size_x = ABS(voodoo->bltSizeX), size_y = ABS(voodoo->bltSizeY); - int x_dir = (voodoo->bltSizeX > 0) ? 1 : -1; - int y_dir = (voodoo->bltSizeY > 0) ? 1 : -1; - int dst_x; - int src_y = voodoo->bltSrcY & 0x7ff, dst_y = voodoo->bltDstY & 0x7ff; - int src_stride = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcXYStride & 0x3f) * 32*2) : (voodoo->bltSrcXYStride & 0xff8); - int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32*2) : (voodoo->bltDstXYStride & 0xff8); - uint32_t src_base_addr = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcBaseAddr & 0x3ff) << 12) : (voodoo->bltSrcBaseAddr & 0x3ffff8); - uint32_t dst_base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); - int x, y; - -/* voodoo_log("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n", - voodoo->bltCommand, voodoo->bltSrcX, voodoo->bltSrcY, voodoo->bltDstX, voodoo->bltDstY, voodoo->bltSizeX, voodoo->bltSizeY, voodoo->bltColorFg, voodoo->bltColorBg);*/ - - wait_for_render_thread_idle(voodoo); - - switch (voodoo->bltCommand & BLIT_COMMAND_MASK) - { - case BLIT_COMMAND_SCREEN_TO_SCREEN: - for (y = 0; y <= size_y; y++) - { - uint16_t *src = (uint16_t *)&voodoo->fb_mem[src_base_addr + src_y*src_stride]; - uint16_t *dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride]; - int src_x = voodoo->bltSrcX, dst_x = voodoo->bltDstX; - - for (x = 0; x <= size_x; x++) - { - uint16_t src_dat = src[src_x]; - uint16_t dst_dat = dst[dst_x]; - int rop = 0; - - if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) - { - if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || - dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) - goto skip_pixel_blit; - } - - if (voodoo->bltCommand & BLIT_SRC_CHROMA) - { - int r = (src_dat >> 11); - int g = (src_dat >> 5) & 0x3f; - int b = src_dat & 0x1f; - - if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && - g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && - b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) - rop |= BLIT_ROP_SRC_PASS; - } - if (voodoo->bltCommand & BLIT_DST_CHROMA) - { - int r = (dst_dat >> 11); - int g = (dst_dat >> 5) & 0x3f; - int b = dst_dat & 0x1f; - - if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && - g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && - b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) - rop |= BLIT_ROP_DST_PASS; - } - - MIX(src_dat, dst_dat, voodoo->bltRop[rop]); - - dst[dst_x] = dst_dat; -skip_pixel_blit: - src_x += x_dir; - dst_x += x_dir; - } - - src_y += y_dir; - dst_y += y_dir; - } - break; - - case BLIT_COMMAND_CPU_TO_SCREEN: - voodoo->blt.dst_x = voodoo->bltDstX; - voodoo->blt.dst_y = voodoo->bltDstY; - voodoo->blt.cur_x = 0; - voodoo->blt.size_x = size_x; - voodoo->blt.size_y = size_y; - voodoo->blt.x_dir = x_dir; - voodoo->blt.y_dir = y_dir; - voodoo->blt.dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32*2) : (voodoo->bltDstXYStride & 0xff8); - break; - - case BLIT_COMMAND_RECT_FILL: - for (y = 0; y <= size_y; y++) - { - uint16_t *dst; - int dst_x = voodoo->bltDstX; - - if (SLI_ENABLED) - { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) - goto skip_line_fill; - dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + (dst_y >> 1) * dst_stride]; - } - else - dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride]; - - for (x = 0; x <= size_x; x++) - { - if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) - { - if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || - dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) - goto skip_pixel_fill; - } - - dst[dst_x] = voodoo->bltColorFg; -skip_pixel_fill: - dst_x += x_dir; - } -skip_line_fill: - dst_y += y_dir; - } - break; - - case BLIT_COMMAND_SGRAM_FILL: - /*32x32 tiles - 2kb*/ - dst_y = voodoo->bltDstY & 0x3ff; - size_x = voodoo->bltSizeX & 0x1ff; //512*8 = 4kb - size_y = voodoo->bltSizeY & 0x3ff; - - dat64 = voodoo->bltColorFg | ((uint64_t)voodoo->bltColorFg << 16) | - ((uint64_t)voodoo->bltColorFg << 32) | ((uint64_t)voodoo->bltColorFg << 48); - - for (y = 0; y <= size_y; y++) - { - uint64_t *dst; - - /*This may be wrong*/ - if (!y) - { - dst_x = voodoo->bltDstX & 0x1ff; - size_x = 511 - dst_x; - } - else if (y < size_y) - { - dst_x = 0; - size_x = 511; - } - else - { - dst_x = 0; - size_x = voodoo->bltSizeX & 0x1ff; - } - - dst = (uint64_t *)&voodoo->fb_mem[(dst_y*512*8 + dst_x*8) & voodoo->fb_mask]; - - for (x = 0; x <= size_x; x++) - dst[x] = dat64; - - dst_y++; - } - break; - - default: - fatal("bad blit command %08x\n", voodoo->bltCommand); - } -} - -static void blit_data(voodoo_t *voodoo, uint32_t data) -{ - int src_bits = 32; - uint32_t base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); - uint32_t addr; - uint16_t *dst; - - if ((voodoo->bltCommand & BLIT_COMMAND_MASK) != BLIT_COMMAND_CPU_TO_SCREEN) - return; - - if (SLI_ENABLED) - { - addr = base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride; - dst = (uint16_t *)&voodoo->fb_mem[addr]; - } - else - { - addr = base_addr + voodoo->blt.dst_y*voodoo->blt.dst_stride; - dst = (uint16_t *)&voodoo->fb_mem[addr]; - } - - if (addr >= voodoo->front_offset && voodoo->row_width) - { - int y = (addr - voodoo->front_offset) / voodoo->row_width; - if (y < voodoo->v_disp) - voodoo->dirty_line[y] = 2; - } - - while (src_bits && voodoo->blt.cur_x <= voodoo->blt.size_x) - { - int r = 0, g = 0, b = 0; - uint16_t src_dat = 0, dst_dat; - int x = (voodoo->blt.x_dir > 0) ? (voodoo->blt.dst_x + voodoo->blt.cur_x) : (voodoo->blt.dst_x - voodoo->blt.cur_x); - int rop = 0; - - switch (voodoo->bltCommand & BLIT_SRC_FORMAT) - { - case BLIT_SRC_1BPP: case BLIT_SRC_1BPP_BYTE_PACKED: - src_dat = (data & 1) ? voodoo->bltColorFg : voodoo->bltColorBg; - data >>= 1; - src_bits--; - break; - case BLIT_SRC_16BPP: - switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) - { - case BLIT_SRC_RGB_ARGB: case BLIT_SRC_RGB_RGBA: - src_dat = data & 0xffff; - break; - case BLIT_SRC_RGB_ABGR: case BLIT_SRC_RGB_BGRA: - src_dat = ((data & 0xf800) >> 11) | (data & 0x07c0) | ((data & 0x0038) << 11); - break; - } - data >>= 16; - src_bits -= 16; - break; - case BLIT_SRC_24BPP: case BLIT_SRC_24BPP_DITHER_2X2: case BLIT_SRC_24BPP_DITHER_4X4: - switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) - { - case BLIT_SRC_RGB_ARGB: - r = (data >> 16) & 0xff; - g = (data >> 8) & 0xff; - b = data & 0xff; - break; - case BLIT_SRC_RGB_ABGR: - r = data & 0xff; - g = (data >> 8) & 0xff; - b = (data >> 16) & 0xff; - break; - case BLIT_SRC_RGB_RGBA: - r = (data >> 24) & 0xff; - g = (data >> 16) & 0xff; - b = (data >> 8) & 0xff; - break; - case BLIT_SRC_RGB_BGRA: - r = (data >> 8) & 0xff; - g = (data >> 16) & 0xff; - b = (data >> 24) & 0xff; - break; - } - switch (voodoo->bltCommand & BLIT_SRC_FORMAT) - { - case BLIT_SRC_24BPP: - src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); - break; - case BLIT_SRC_24BPP_DITHER_2X2: - r = dither_rb2x2[r][voodoo->blt.dst_y & 1][x & 1]; - g = dither_g2x2[g][voodoo->blt.dst_y & 1][x & 1]; - b = dither_rb2x2[b][voodoo->blt.dst_y & 1][x & 1]; - src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); - break; - case BLIT_SRC_24BPP_DITHER_4X4: - r = dither_rb[r][voodoo->blt.dst_y & 3][x & 3]; - g = dither_g[g][voodoo->blt.dst_y & 3][x & 3]; - b = dither_rb[b][voodoo->blt.dst_y & 3][x & 3]; - src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); - break; - } - src_bits = 0; - break; - } - - if (SLI_ENABLED) - { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) - goto skip_pixel; - } - - if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) - { - if (x < voodoo->bltClipLeft || x >= voodoo->bltClipRight || - voodoo->blt.dst_y < voodoo->bltClipLowY || voodoo->blt.dst_y >= voodoo->bltClipHighY) - goto skip_pixel; - } - - dst_dat = dst[x]; - - if (voodoo->bltCommand & BLIT_SRC_CHROMA) - { - r = (src_dat >> 11); - g = (src_dat >> 5) & 0x3f; - b = src_dat & 0x1f; - - if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && - g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && - b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) - rop |= BLIT_ROP_SRC_PASS; - } - if (voodoo->bltCommand & BLIT_DST_CHROMA) - { - r = (dst_dat >> 11); - g = (dst_dat >> 5) & 0x3f; - b = dst_dat & 0x1f; - - if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && - g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && - b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) - rop |= BLIT_ROP_DST_PASS; - } - - MIX(src_dat, dst_dat, voodoo->bltRop[rop]); - - dst[x] = dst_dat; - -skip_pixel: - voodoo->blt.cur_x++; - } - - if (voodoo->blt.cur_x > voodoo->blt.size_x) - { - voodoo->blt.size_y--; - if (voodoo->blt.size_y >= 0) - { - voodoo->blt.cur_x = 0; - voodoo->blt.dst_y += voodoo->blt.y_dir; - } - } -} - -enum -{ - CHIP_FBI = 0x1, - CHIP_TREX0 = 0x2, - CHIP_TREX1 = 0x4, - CHIP_TREX2 = 0x8 -}; - -static void wait_for_swap_complete(voodoo_t *voodoo) -{ - while (voodoo->swap_pending) - { - thread_wait_event(voodoo->wake_fifo_thread, -1); - thread_reset_event(voodoo->wake_fifo_thread); - if ((voodoo->swap_pending && voodoo->flush) || FIFO_ENTRIES >= 65536) - { - /*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/ - memset(voodoo->dirty_line, 1, 1024); - voodoo->front_offset = voodoo->params.front_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; - break; - } - } -} - -static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - union - { - uint32_t i; - float f; - } tempif; - int ad21 = addr & (1 << 21); - int chip = (addr >> 10) & 0xf; - if (!chip) - chip = 0xf; - - tempif.i = val; -//voodoo_log("voodoo_reg_write_l: addr=%08x val=%08x(%f) chip=%x\n", addr, val, tempif.f, chip); - addr &= 0x3fc; - - if ((voodoo->fbiInit3 & FBIINIT3_REMAP) && addr < 0x100 && ad21) - addr |= 0x400; - switch (addr) - { - case SST_swapbufferCMD: -// voodoo_log(" start swap buffer command\n"); - - if (TRIPLE_BUFFER) - { - voodoo->disp_buffer = (voodoo->disp_buffer + 1) % 3; - voodoo->draw_buffer = (voodoo->draw_buffer + 1) % 3; - } - else - { - voodoo->disp_buffer = !voodoo->disp_buffer; - voodoo->draw_buffer = !voodoo->draw_buffer; - } - voodoo_recalc(voodoo); - - voodoo->params.swapbufferCMD = val; - - voodoo_log("Swap buffer %08x %d %p %i\n", val, voodoo->swap_count, &voodoo->swap_count, (voodoo == voodoo->set->voodoos[1]) ? 1 : 0); -// voodoo->front_offset = params->front_offset; - wait_for_render_thread_idle(voodoo); - if (!(val & 1)) - { - memset(voodoo->dirty_line, 1, 1024); - voodoo->front_offset = voodoo->params.front_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - } - else if (TRIPLE_BUFFER) - { - if (voodoo->swap_pending) - wait_for_swap_complete(voodoo); - - voodoo->swap_interval = (val >> 1) & 0xff; - voodoo->swap_offset = voodoo->params.front_offset; - voodoo->swap_pending = 1; - } - else - { - voodoo->swap_interval = (val >> 1) & 0xff; - voodoo->swap_offset = voodoo->params.front_offset; - voodoo->swap_pending = 1; - - wait_for_swap_complete(voodoo); - } - voodoo->cmd_read++; - break; - - case SST_vertexAx: case SST_remap_vertexAx: - voodoo->params.vertexAx = val & 0xffff; - break; - case SST_vertexAy: case SST_remap_vertexAy: - voodoo->params.vertexAy = val & 0xffff; - break; - case SST_vertexBx: case SST_remap_vertexBx: - voodoo->params.vertexBx = val & 0xffff; - break; - case SST_vertexBy: case SST_remap_vertexBy: - voodoo->params.vertexBy = val & 0xffff; - break; - case SST_vertexCx: case SST_remap_vertexCx: - voodoo->params.vertexCx = val & 0xffff; - break; - case SST_vertexCy: case SST_remap_vertexCy: - voodoo->params.vertexCy = val & 0xffff; - break; - - case SST_startR: case SST_remap_startR: - voodoo->params.startR = val & 0xffffff; - break; - case SST_startG: case SST_remap_startG: - voodoo->params.startG = val & 0xffffff; - break; - case SST_startB: case SST_remap_startB: - voodoo->params.startB = val & 0xffffff; - break; - case SST_startZ: case SST_remap_startZ: - voodoo->params.startZ = val; - break; - case SST_startA: case SST_remap_startA: - voodoo->params.startA = val & 0xffffff; - break; - case SST_startS: case SST_remap_startS: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startS = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startS = ((int64_t)(int32_t)val) << 14; - break; - case SST_startT: case SST_remap_startT: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startT = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startT = ((int64_t)(int32_t)val) << 14; - break; - case SST_startW: case SST_remap_startW: - if (chip & CHIP_FBI) - voodoo->params.startW = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startW = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startW = (int64_t)(int32_t)val << 2; - break; - - case SST_dRdX: case SST_remap_dRdX: - voodoo->params.dRdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dGdX: case SST_remap_dGdX: - voodoo->params.dGdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dBdX: case SST_remap_dBdX: - voodoo->params.dBdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dZdX: case SST_remap_dZdX: - voodoo->params.dZdX = val; - break; - case SST_dAdX: case SST_remap_dAdX: - voodoo->params.dAdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dSdX: case SST_remap_dSdX: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdX = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdX = ((int64_t)(int32_t)val) << 14; - break; - case SST_dTdX: case SST_remap_dTdX: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdX = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdX = ((int64_t)(int32_t)val) << 14; - break; - case SST_dWdX: case SST_remap_dWdX: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdX = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdX = (int64_t)(int32_t)val << 2; - if (chip & CHIP_FBI) - voodoo->params.dWdX = (int64_t)(int32_t)val << 2; - break; - - case SST_dRdY: case SST_remap_dRdY: - voodoo->params.dRdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dGdY: case SST_remap_dGdY: - voodoo->params.dGdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dBdY: case SST_remap_dBdY: - voodoo->params.dBdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dZdY: case SST_remap_dZdY: - voodoo->params.dZdY = val; - break; - case SST_dAdY: case SST_remap_dAdY: - voodoo->params.dAdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dSdY: case SST_remap_dSdY: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdY = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdY = ((int64_t)(int32_t)val) << 14; - break; - case SST_dTdY: case SST_remap_dTdY: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdY = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdY = ((int64_t)(int32_t)val) << 14; - break; - case SST_dWdY: case SST_remap_dWdY: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdY = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdY = (int64_t)(int32_t)val << 2; - if (chip & CHIP_FBI) - voodoo->params.dWdY = (int64_t)(int32_t)val << 2; - break; - - case SST_triangleCMD: case SST_remap_triangleCMD: - voodoo->params.sign = val & (1 << 31); - - if (voodoo->ncc_dirty[0]) - voodoo_update_ncc(voodoo, 0); - if (voodoo->ncc_dirty[1]) - voodoo_update_ncc(voodoo, 1); - voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; - - queue_triangle(voodoo, &voodoo->params); - - voodoo->cmd_read++; - break; - - case SST_fvertexAx: case SST_remap_fvertexAx: - voodoo->fvertexAx.i = val; - voodoo->params.vertexAx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexAx.f * 16.0f) & 0xffff; - break; - case SST_fvertexAy: case SST_remap_fvertexAy: - voodoo->fvertexAy.i = val; - voodoo->params.vertexAy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexAy.f * 16.0f) & 0xffff; - break; - case SST_fvertexBx: case SST_remap_fvertexBx: - voodoo->fvertexBx.i = val; - voodoo->params.vertexBx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexBx.f * 16.0f) & 0xffff; - break; - case SST_fvertexBy: case SST_remap_fvertexBy: - voodoo->fvertexBy.i = val; - voodoo->params.vertexBy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexBy.f * 16.0f) & 0xffff; - break; - case SST_fvertexCx: case SST_remap_fvertexCx: - voodoo->fvertexCx.i = val; - voodoo->params.vertexCx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexCx.f * 16.0f) & 0xffff; - break; - case SST_fvertexCy: case SST_remap_fvertexCy: - voodoo->fvertexCy.i = val; - voodoo->params.vertexCy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexCy.f * 16.0f) & 0xffff; - break; - - case SST_fstartR: case SST_remap_fstartR: - tempif.i = val; - voodoo->params.startR = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartG: case SST_remap_fstartG: - tempif.i = val; - voodoo->params.startG = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartB: case SST_remap_fstartB: - tempif.i = val; - voodoo->params.startB = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartZ: case SST_remap_fstartZ: - tempif.i = val; - voodoo->params.startZ = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartA: case SST_remap_fstartA: - tempif.i = val; - voodoo->params.startA = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartS: case SST_remap_fstartS: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startS = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startS = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fstartT: case SST_remap_fstartT: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startT = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startT = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fstartW: case SST_remap_fstartW: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startW = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startW = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_FBI) - voodoo->params.startW = (int64_t)(tempif.f * 4294967296.0f); - break; - - case SST_fdRdX: case SST_remap_fdRdX: - tempif.i = val; - voodoo->params.dRdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdGdX: case SST_remap_fdGdX: - tempif.i = val; - voodoo->params.dGdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdBdX: case SST_remap_fdBdX: - tempif.i = val; - voodoo->params.dBdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdZdX: case SST_remap_fdZdX: - tempif.i = val; - voodoo->params.dZdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdAdX: case SST_remap_fdAdX: - tempif.i = val; - voodoo->params.dAdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdSdX: case SST_remap_fdSdX: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdX = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdTdX: case SST_remap_fdTdX: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdX = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdWdX: case SST_remap_fdWdX: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_FBI) - voodoo->params.dWdX = (int64_t)(tempif.f * 4294967296.0f); - break; - - case SST_fdRdY: case SST_remap_fdRdY: - tempif.i = val; - voodoo->params.dRdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdGdY: case SST_remap_fdGdY: - tempif.i = val; - voodoo->params.dGdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdBdY: case SST_remap_fdBdY: - tempif.i = val; - voodoo->params.dBdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdZdY: case SST_remap_fdZdY: - tempif.i = val; - voodoo->params.dZdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdAdY: case SST_remap_fdAdY: - tempif.i = val; - voodoo->params.dAdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdSdY: case SST_remap_fdSdY: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdY = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdTdY: case SST_remap_fdTdY: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdY = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdWdY: case SST_remap_fdWdY: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_FBI) - voodoo->params.dWdY = (int64_t)(tempif.f * 4294967296.0f); - break; - - case SST_ftriangleCMD: - voodoo->params.sign = val & (1 << 31); - - if (voodoo->ncc_dirty[0]) - voodoo_update_ncc(voodoo, 0); - if (voodoo->ncc_dirty[1]) - voodoo_update_ncc(voodoo, 1); - voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; - - queue_triangle(voodoo, &voodoo->params); - - voodoo->cmd_read++; - break; - - case SST_fbzColorPath: - voodoo->params.fbzColorPath = val; - voodoo->rgb_sel = val & 3; - break; - - case SST_fogMode: - voodoo->params.fogMode = val; - break; - case SST_alphaMode: - voodoo->params.alphaMode = val; - break; - case SST_fbzMode: - voodoo->params.fbzMode = val; - voodoo_recalc(voodoo); - break; - case SST_lfbMode: - voodoo->lfbMode = val; - voodoo_recalc(voodoo); - break; - - case SST_clipLeftRight: - if (voodoo->type >= VOODOO_2) - { - voodoo->params.clipRight = val & 0xfff; - voodoo->params.clipLeft = (val >> 16) & 0xfff; - } - else - { - voodoo->params.clipRight = val & 0x3ff; - voodoo->params.clipLeft = (val >> 16) & 0x3ff; - } - break; - case SST_clipLowYHighY: - if (voodoo->type >= VOODOO_2) - { - voodoo->params.clipHighY = val & 0xfff; - voodoo->params.clipLowY = (val >> 16) & 0xfff; - } - else - { - voodoo->params.clipHighY = val & 0x3ff; - voodoo->params.clipLowY = (val >> 16) & 0x3ff; - } - break; - - case SST_nopCMD: - voodoo->cmd_read++; - voodoo->fbiPixelsIn = 0; - voodoo->fbiChromaFail = 0; - voodoo->fbiZFuncFail = 0; - voodoo->fbiAFuncFail = 0; - voodoo->fbiPixelsOut = 0; - break; - case SST_fastfillCMD: - wait_for_render_thread_idle(voodoo); - voodoo_fastfill(voodoo, &voodoo->params); - voodoo->cmd_read++; - break; - - case SST_fogColor: - voodoo->params.fogColor.r = (val >> 16) & 0xff; - voodoo->params.fogColor.g = (val >> 8) & 0xff; - voodoo->params.fogColor.b = val & 0xff; - break; - - case SST_zaColor: - voodoo->params.zaColor = val; - break; - case SST_chromaKey: - voodoo->params.chromaKey_r = (val >> 16) & 0xff; - voodoo->params.chromaKey_g = (val >> 8) & 0xff; - voodoo->params.chromaKey_b = val & 0xff; - voodoo->params.chromaKey = val & 0xffffff; - break; - case SST_stipple: - voodoo->params.stipple = val; - break; - case SST_color0: - voodoo->params.color0 = val; - break; - case SST_color1: - voodoo->params.color1 = val; - break; - - case SST_fogTable00: case SST_fogTable01: case SST_fogTable02: case SST_fogTable03: - case SST_fogTable04: case SST_fogTable05: case SST_fogTable06: case SST_fogTable07: - case SST_fogTable08: case SST_fogTable09: case SST_fogTable0a: case SST_fogTable0b: - case SST_fogTable0c: case SST_fogTable0d: case SST_fogTable0e: case SST_fogTable0f: - case SST_fogTable10: case SST_fogTable11: case SST_fogTable12: case SST_fogTable13: - case SST_fogTable14: case SST_fogTable15: case SST_fogTable16: case SST_fogTable17: - case SST_fogTable18: case SST_fogTable19: case SST_fogTable1a: case SST_fogTable1b: - case SST_fogTable1c: case SST_fogTable1d: case SST_fogTable1e: case SST_fogTable1f: - addr = (addr - SST_fogTable00) >> 1; - voodoo->params.fogTable[addr].dfog = val & 0xff; - voodoo->params.fogTable[addr].fog = (val >> 8) & 0xff; - voodoo->params.fogTable[addr+1].dfog = (val >> 16) & 0xff; - voodoo->params.fogTable[addr+1].fog = (val >> 24) & 0xff; - break; - - case SST_clutData: - voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; - voodoo->clutData[(val >> 24) & 0x3f].g = (val >> 8) & 0xff; - voodoo->clutData[(val >> 24) & 0x3f].r = (val >> 16) & 0xff; - if (val & 0x20000000) - { - voodoo->clutData[(val >> 24) & 0x3f].b = 255; - voodoo->clutData[(val >> 24) & 0x3f].g = 255; - voodoo->clutData[(val >> 24) & 0x3f].r = 255; - } - voodoo->clutData_dirty = 1; - break; - - case SST_sSetupMode: - voodoo->sSetupMode = val; - break; - case SST_sVx: - tempif.i = val; - voodoo->verts[3].sVx = tempif.f; -// voodoo_log("sVx[%i]=%f\n", voodoo->vertex_num, tempif.f); - break; - case SST_sVy: - tempif.i = val; - voodoo->verts[3].sVy = tempif.f; -// voodoo_log("sVy[%i]=%f\n", voodoo->vertex_num, tempif.f); - break; - case SST_sARGB: - voodoo->verts[3].sBlue = (float)(val & 0xff); - voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff); - voodoo->verts[3].sRed = (float)((val >> 16) & 0xff); - voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff); - break; - case SST_sRed: - tempif.i = val; - voodoo->verts[3].sRed = tempif.f; - break; - case SST_sGreen: - tempif.i = val; - voodoo->verts[3].sGreen = tempif.f; - break; - case SST_sBlue: - tempif.i = val; - voodoo->verts[3].sBlue = tempif.f; - break; - case SST_sAlpha: - tempif.i = val; - voodoo->verts[3].sAlpha = tempif.f; - break; - case SST_sVz: - tempif.i = val; - voodoo->verts[3].sVz = tempif.f; - break; - case SST_sWb: - tempif.i = val; - voodoo->verts[3].sWb = tempif.f; - break; - case SST_sW0: - tempif.i = val; - voodoo->verts[3].sW0 = tempif.f; - break; - case SST_sS0: - tempif.i = val; - voodoo->verts[3].sS0 = tempif.f; - break; - case SST_sT0: - tempif.i = val; - voodoo->verts[3].sT0 = tempif.f; - break; - case SST_sW1: - tempif.i = val; - voodoo->verts[3].sW1 = tempif.f; - break; - case SST_sS1: - tempif.i = val; - voodoo->verts[3].sS1 = tempif.f; - break; - case SST_sT1: - tempif.i = val; - voodoo->verts[3].sT1 = tempif.f; - break; - - case SST_sBeginTriCMD: -// voodoo_log("sBeginTriCMD %i %f\n", voodoo->vertex_num, voodoo->verts[4].sVx); - voodoo->verts[0] = voodoo->verts[3]; - voodoo->vertex_num = 1; - voodoo->num_verticies = 1; - break; - case SST_sDrawTriCMD: -// voodoo_log("sDrawTriCMD %i %i %i\n", voodoo->num_verticies, voodoo->vertex_num, voodoo->sSetupMode & SETUPMODE_STRIP_MODE); - if (voodoo->vertex_num == 3) - voodoo->vertex_num = (voodoo->sSetupMode & SETUPMODE_STRIP_MODE) ? 1 : 0; - voodoo->verts[voodoo->vertex_num] = voodoo->verts[3]; - - voodoo->num_verticies++; - voodoo->vertex_num++; - if (voodoo->num_verticies == 3) - { -// voodoo_log("triangle_setup\n"); - triangle_setup(voodoo); - - voodoo->num_verticies = 2; - } - if (voodoo->vertex_num == 4) - fatal("sDrawTriCMD overflow\n"); - break; - - case SST_bltSrcBaseAddr: - voodoo->bltSrcBaseAddr = val & 0x3fffff; - break; - case SST_bltDstBaseAddr: -// voodoo_log("Write bltDstBaseAddr %08x\n", val); - voodoo->bltDstBaseAddr = val & 0x3fffff; - break; - case SST_bltXYStrides: - voodoo->bltSrcXYStride = val & 0xfff; - voodoo->bltDstXYStride = (val >> 16) & 0xfff; -// voodoo_log("Write bltXYStrides %08x\n", val); - break; - case SST_bltSrcChromaRange: - voodoo->bltSrcChromaRange = val; - voodoo->bltSrcChromaMinB = val & 0x1f; - voodoo->bltSrcChromaMinG = (val >> 5) & 0x3f; - voodoo->bltSrcChromaMinR = (val >> 11) & 0x1f; - voodoo->bltSrcChromaMaxB = (val >> 16) & 0x1f; - voodoo->bltSrcChromaMaxG = (val >> 21) & 0x3f; - voodoo->bltSrcChromaMaxR = (val >> 27) & 0x1f; - break; - case SST_bltDstChromaRange: - voodoo->bltDstChromaRange = val; - voodoo->bltDstChromaMinB = val & 0x1f; - voodoo->bltDstChromaMinG = (val >> 5) & 0x3f; - voodoo->bltDstChromaMinR = (val >> 11) & 0x1f; - voodoo->bltDstChromaMaxB = (val >> 16) & 0x1f; - voodoo->bltDstChromaMaxG = (val >> 21) & 0x3f; - voodoo->bltDstChromaMaxR = (val >> 27) & 0x1f; - break; - case SST_bltClipX: - voodoo->bltClipRight = val & 0xfff; - voodoo->bltClipLeft = (val >> 16) & 0xfff; - break; - case SST_bltClipY: - voodoo->bltClipHighY = val & 0xfff; - voodoo->bltClipLowY = (val >> 16) & 0xfff; - break; - - case SST_bltSrcXY: - voodoo->bltSrcX = val & 0x7ff; - voodoo->bltSrcY = (val >> 16) & 0x7ff; - break; - case SST_bltDstXY: -// voodoo_log("Write bltDstXY %08x\n", val); - voodoo->bltDstX = val & 0x7ff; - voodoo->bltDstY = (val >> 16) & 0x7ff; - if (val & (1 << 31)) - blit_start(voodoo); - break; - case SST_bltSize: -// voodoo_log("Write bltSize %08x\n", val); - voodoo->bltSizeX = val & 0xfff; - if (voodoo->bltSizeX & 0x800) - voodoo->bltSizeX |= 0xfffff000; - voodoo->bltSizeY = (val >> 16) & 0xfff; - if (voodoo->bltSizeY & 0x800) - voodoo->bltSizeY |= 0xfffff000; - if (val & (1 << 31)) - blit_start(voodoo); - break; - case SST_bltRop: - voodoo->bltRop[0] = val & 0xf; - voodoo->bltRop[1] = (val >> 4) & 0xf; - voodoo->bltRop[2] = (val >> 8) & 0xf; - voodoo->bltRop[3] = (val >> 12) & 0xf; - break; - case SST_bltColor: -// voodoo_log("Write bltColor %08x\n", val); - voodoo->bltColorFg = val & 0xffff; - voodoo->bltColorBg = (val >> 16) & 0xffff; - break; - - case SST_bltCommand: - voodoo->bltCommand = val; -// voodoo_log("Write bltCommand %08x\n", val); - if (val & (1 << 31)) - blit_start(voodoo); - break; - case SST_bltData: - blit_data(voodoo, val); - break; - - case SST_textureMode: - if (chip & CHIP_TREX0) - { - voodoo->params.textureMode[0] = val; - voodoo->params.tformat[0] = (val >> 8) & 0xf; - } - if (chip & CHIP_TREX1) - { - voodoo->params.textureMode[1] = val; - voodoo->params.tformat[1] = (val >> 8) & 0xf; - } - break; - case SST_tLOD: - if (chip & CHIP_TREX0) - { - voodoo->params.tLOD[0] = val; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - voodoo->params.tLOD[1] = val; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_tDetail: - if (chip & CHIP_TREX0) - { - voodoo->params.detail_max[0] = val & 0xff; - voodoo->params.detail_bias[0] = (val >> 8) & 0x3f; - voodoo->params.detail_scale[0] = (val >> 14) & 7; - } - if (chip & CHIP_TREX1) - { - voodoo->params.detail_max[1] = val & 0xff; - voodoo->params.detail_bias[1] = (val >> 8) & 0x3f; - voodoo->params.detail_scale[1] = (val >> 14) & 7; - } - break; - case SST_texBaseAddr: - if (chip & CHIP_TREX0) - { - voodoo->params.texBaseAddr[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - voodoo->params.texBaseAddr[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_texBaseAddr1: - if (chip & CHIP_TREX0) - { - voodoo->params.texBaseAddr1[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - voodoo->params.texBaseAddr1[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_texBaseAddr2: - if (chip & CHIP_TREX0) - { - voodoo->params.texBaseAddr2[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - voodoo->params.texBaseAddr2[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_texBaseAddr38: - if (chip & CHIP_TREX0) - { - voodoo->params.texBaseAddr38[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - voodoo->params.texBaseAddr38[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - - case SST_trexInit1: - if (chip & CHIP_TREX0) - voodoo->trexInit1[0] = val; - if (chip & CHIP_TREX1) - voodoo->trexInit1[1] = val; - break; - - case SST_nccTable0_Y0: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].y[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].y[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable0_Y1: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].y[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].y[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable0_Y2: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].y[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].y[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable0_Y3: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].y[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].y[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - - case SST_nccTable0_I0: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_I2: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q0: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].q[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].q[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q2: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - if (val & (1 << 31)) - { - int p = (val >> 23) & 0xfe; - if (chip & CHIP_TREX0) - { - voodoo->palette[0][p].u = val | 0xff000000; - voodoo->palette_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->palette[1][p].u = val | 0xff000000; - voodoo->palette_dirty[1] = 1; - } - } - break; - - case SST_nccTable0_I1: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_I3: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q1: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].q[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].q[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q3: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].q[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].q[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - if (val & (1 << 31)) - { - int p = ((val >> 23) & 0xfe) | 0x01; - if (chip & CHIP_TREX0) - { - voodoo->palette[0][p].u = val | 0xff000000; - voodoo->palette_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->palette[1][p].u = val | 0xff000000; - voodoo->palette_dirty[1] = 1; - } - } - break; - - case SST_nccTable1_Y0: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].y[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].y[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Y1: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].y[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].y[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Y2: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].y[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].y[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Y3: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].y[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].y[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I0: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].i[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].i[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I1: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].i[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].i[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I2: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].i[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].i[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I3: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].i[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].i[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q0: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].q[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].q[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q1: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].q[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].q[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q2: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].q[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].q[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q3: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].q[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].q[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - - case SST_userIntrCMD: - fatal("userIntrCMD write %08x from FIFO\n", val); - break; - } -} - - -static uint16_t voodoo_fb_readw(uint32_t addr, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - int x, y; - uint32_t read_addr; - uint16_t temp; - - x = (addr >> 1) & 0x3ff; - y = (addr >> 11) & 0x3ff; - - if (SLI_ENABLED) - { - voodoo_set_t *set = voodoo->set; - - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; - - y >>= 1; - } - - read_addr = voodoo->fb_read_offset + (x << 1) + (y * voodoo->row_width); - - if (read_addr > voodoo->fb_mask) - return 0xffff; - - temp = *(uint16_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); - -// voodoo_log("voodoo_fb_readw : %08X %08X %i %i %08X %08X %08x:%08x %i\n", addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++); - return temp; -} -static uint32_t voodoo_fb_readl(uint32_t addr, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - int x, y; - uint32_t read_addr; - uint32_t temp; - - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - - if (SLI_ENABLED) - { - voodoo_set_t *set = voodoo->set; - - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; - - y >>= 1; - } - - read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); - - if (read_addr > voodoo->fb_mask) - return 0xffffffff; - - temp = *(uint32_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); - -// voodoo_log("voodoo_fb_readl : %08X %08x %08X x=%i y=%i %08X %08X %08x:%08x %i ro=%08x rw=%i\n", addr, read_addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++, voodoo->fb_read_offset, voodoo->row_width); - return temp; -} - -static inline uint16_t do_dither(voodoo_params_t *params, rgba8_t col, int x, int y) -{ - int r, g, b; - - if (dither) - { - if (dither2x2) - { - r = dither_rb2x2[col.r][y & 1][x & 1]; - g = dither_g2x2[col.g][y & 1][x & 1]; - b = dither_rb2x2[col.b][y & 1][x & 1]; - } - else - { - r = dither_rb[col.r][y & 3][x & 3]; - g = dither_g[col.g][y & 3][x & 3]; - b = dither_rb[col.b][y & 3][x & 3]; - } - } - else - { - r = col.r >> 3; - g = col.g >> 2; - b = col.b >> 3; - } - - return b | (g << 5) | (r << 11); -} - -static void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - voodoo_params_t *params = &voodoo->params; - int x, y; - uint32_t write_addr, write_addr_aux; - rgba8_t colour_data; - uint16_t depth_data; - uint8_t alpha_data; - int write_mask = 0; - - colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0; - - depth_data = voodoo->params.zaColor & 0xffff; - alpha_data = voodoo->params.zaColor >> 24; - -// while (!RB_EMPTY) -// thread_reset_event(voodoo->not_full_event); - -// voodoo_log("voodoo_fb_writew : %08X %04X\n", addr, val); - - - switch (voodoo->lfbMode & LFB_FORMAT_MASK) - { - case LFB_FORMAT_RGB565: - colour_data = rgb565[val]; - alpha_data = 0xff; - write_mask = LFB_WRITE_COLOUR; - break; - case LFB_FORMAT_RGB555: - colour_data = argb1555[val]; - alpha_data = 0xff; - write_mask = LFB_WRITE_COLOUR; - break; - case LFB_FORMAT_ARGB1555: - colour_data = argb1555[val]; - alpha_data = colour_data.a; - write_mask = LFB_WRITE_COLOUR; - break; - case LFB_FORMAT_DEPTH: - depth_data = val; - write_mask = LFB_WRITE_DEPTH; - break; - - default: - fatal("voodoo_fb_writew : bad LFB format %08X\n", voodoo->lfbMode); - } - - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - - if (SLI_ENABLED) - { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) - return; - y >>= 1; - } - - - if (voodoo->fb_write_offset == voodoo->params.front_offset) - voodoo->dirty_line[y] = 1; - - write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); - write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); - -// voodoo_log("fb_writew %08x %i %i %i %08x\n", addr, x, y, voodoo->row_width, write_addr); - - if (voodoo->lfbMode & 0x100) - { - { - rgba8_t write_data = colour_data; - uint16_t new_depth = depth_data; - - if (params->fbzMode & FBZ_DEPTH_ENABLE) - { - uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); - - DEPTH_TEST(new_depth); - } - - if ((params->fbzMode & FBZ_CHROMAKEY) && - write_data.r == params->chromaKey_r && - write_data.g == params->chromaKey_g && - write_data.b == params->chromaKey_b) - goto skip_pixel; - - if (params->fogMode & FOG_ENABLE) - { - int32_t z = new_depth << 12; - int64_t w_depth = (int64_t)(int32_t)new_depth; - int32_t ia = alpha_data << 12; - - APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); - } - - if (params->alphaMode & 1) - ALPHA_TEST(alpha_data); - - if (params->alphaMode & (1 << 4)) - { - uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]); - int dest_r, dest_g, dest_b, dest_a; - - dest_r = (dat >> 8) & 0xf8; - dest_g = (dat >> 3) & 0xfc; - dest_b = (dat << 3) & 0xf8; - dest_r |= (dest_r >> 5); - dest_g |= (dest_g >> 6); - dest_b |= (dest_b >> 5); - dest_a = 0xff; - - ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data); - } - - if (params->fbzMode & FBZ_RGB_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, x >> 1, y); - if (params->fbzMode & FBZ_DEPTH_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; - -skip_pixel: - (void)x; - } - } - else - { - if (write_mask & LFB_WRITE_COLOUR) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data, x >> 1, y); - if (write_mask & LFB_WRITE_DEPTH) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data; - } -} - - -static void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - voodoo_params_t *params = &voodoo->params; - int x, y; - uint32_t write_addr, write_addr_aux; - rgba8_t colour_data[2]; - uint16_t depth_data[2]; - uint8_t alpha_data[2]; - int write_mask = 0, count = 1; - - depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff; - alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24; -// while (!RB_EMPTY) -// thread_reset_event(voodoo->not_full_event); - -// voodoo_log("voodoo_fb_writel : %08X %08X\n", addr, val); - - switch (voodoo->lfbMode & LFB_FORMAT_MASK) - { - case LFB_FORMAT_RGB565: - colour_data[0] = rgb565[val & 0xffff]; - colour_data[1] = rgb565[val >> 16]; - write_mask = LFB_WRITE_COLOUR; - count = 2; - break; - case LFB_FORMAT_RGB555: - colour_data[0] = argb1555[val & 0xffff]; - colour_data[1] = argb1555[val >> 16]; - write_mask = LFB_WRITE_COLOUR; - count = 2; - break; - case LFB_FORMAT_ARGB1555: - colour_data[0] = argb1555[val & 0xffff]; - alpha_data[0] = colour_data[0].a; - colour_data[1] = argb1555[val >> 16]; - alpha_data[1] = colour_data[1].a; - write_mask = LFB_WRITE_COLOUR; - count = 2; - break; - - case LFB_FORMAT_ARGB8888: - colour_data[0].b = val & 0xff; - colour_data[0].g = (val >> 8) & 0xff; - colour_data[0].r = (val >> 16) & 0xff; - alpha_data[0] = (val >> 24) & 0xff; - write_mask = LFB_WRITE_COLOUR; - addr >>= 1; - break; - - case LFB_FORMAT_DEPTH: - depth_data[0] = val; - depth_data[1] = val >> 16; - write_mask = LFB_WRITE_DEPTH; - count = 2; - break; - - default: - fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo->lfbMode); - } - - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - - if (SLI_ENABLED) - { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) - return; - y >>= 1; - } - - if (voodoo->fb_write_offset == voodoo->params.front_offset) - voodoo->dirty_line[y] = 1; - - write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); - write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); - -// voodoo_log("fb_writel %08x x=%i y=%i rw=%i %08x wo=%08x\n", addr, x, y, voodoo->row_width, write_addr, voodoo->fb_write_offset); - - if (voodoo->lfbMode & 0x100) - { - int c; - - for (c = 0; c < count; c++) - { - rgba8_t write_data = colour_data[c]; - uint16_t new_depth = depth_data[c]; - - if (params->fbzMode & FBZ_DEPTH_ENABLE) - { - uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); - - DEPTH_TEST(new_depth); - } - - if ((params->fbzMode & FBZ_CHROMAKEY) && - write_data.r == params->chromaKey_r && - write_data.g == params->chromaKey_g && - write_data.b == params->chromaKey_b) - goto skip_pixel; - - if (params->fogMode & FOG_ENABLE) - { - int32_t z = new_depth << 12; - int64_t w_depth = new_depth; - int32_t ia = alpha_data[c] << 12; - - APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); - } - - if (params->alphaMode & 1) - ALPHA_TEST(alpha_data[c]); - - if (params->alphaMode & (1 << 4)) - { - uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]); - int dest_r, dest_g, dest_b, dest_a; - - dest_r = (dat >> 8) & 0xf8; - dest_g = (dat >> 3) & 0xfc; - dest_b = (dat << 3) & 0xf8; - dest_r |= (dest_r >> 5); - dest_g |= (dest_g >> 6); - dest_b |= (dest_b >> 5); - dest_a = 0xff; - - ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data[c]); - } - - if (params->fbzMode & FBZ_RGB_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, (x >> 1) + c, y); - if (params->fbzMode & FBZ_DEPTH_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; - -skip_pixel: - write_addr += 2; - write_addr_aux += 2; - } - } - else - { - int c; - - for (c = 0; c < count; c++) - { - if (write_mask & LFB_WRITE_COLOUR) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data[c], (x >> 1) + c, y); - if (write_mask & LFB_WRITE_DEPTH) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data[c]; - - write_addr += 2; - write_addr_aux += 2; - } - } -} - -static void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) -{ - int lod, s, t; - voodoo_t *voodoo = (voodoo_t *)p; - int tmu; - - if (addr & 0x400000) - return; /*TREX != 0*/ - - tmu = (addr & 0x200000) ? 1 : 0; - - if (tmu && !voodoo->dual_tmus) - return; - -// voodoo_log("voodoo_tex_writel : %08X %08X %i\n", addr, val, voodoo->params.tformat); - - lod = (addr >> 17) & 0xf; - t = (addr >> 9) & 0xff; - if (voodoo->params.tformat[tmu] & 8) - s = (addr >> 1) & 0xfe; - else - { - if (voodoo->params.textureMode[tmu] & (1 << 31)) - s = addr & 0xfc; - else - s = (addr >> 1) & 0xfc; - } - - if (lod > LOD_MAX) - return; - -// if (addr >= 0x200000) -// return; - - if (voodoo->params.tformat[tmu] & 8) - addr = voodoo->params.tex_base[tmu][lod] + s*2 + (t << voodoo->params.tex_shift[tmu][lod])*2; - else - addr = voodoo->params.tex_base[tmu][lod] + s + (t << voodoo->params.tex_shift[tmu][lod]); - if (voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) - { -// voodoo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); - flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu); - } - *(uint32_t *)(&voodoo->tex_mem[tmu][addr & voodoo->texture_mask]) = val; -} - -#define WAKE_DELAY (TIMER_USEC * 100) -static inline void wake_fifo_thread(voodoo_t *voodoo) -{ - if (!voodoo->wake_timer) - { - /*Don't wake FIFO thread immediately - if we do that it will probably - process one word and go back to sleep, requiring it to be woken on - almost every write. Instead, wait a short while so that the CPU - emulation writes more data so we have more batched-up work.*/ - timer_process(); - voodoo->wake_timer = WAKE_DELAY; - timer_update_outstanding(); - } -} - -static inline void wake_fifo_thread_now(voodoo_t *voodoo) -{ - thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ -} - -static void voodoo_wake_timer(void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - - voodoo->wake_timer = 0; - - thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ -} - -static inline void queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val) -{ - fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_write_idx & FIFO_MASK]; - - while (FIFO_FULL) - { - thread_reset_event(voodoo->fifo_not_full_event); - if (FIFO_FULL) - { - thread_wait_event(voodoo->fifo_not_full_event, 1); /*Wait for room in ringbuffer*/ - if (FIFO_FULL) - wake_fifo_thread_now(voodoo); - } - } - - fifo->val = val; - fifo->addr_type = addr_type; - - voodoo->fifo_write_idx++; - - if (FIFO_ENTRIES > 0xe000) - wake_fifo_thread(voodoo); -} - -static uint16_t voodoo_readw(uint32_t addr, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - - addr &= 0xffffff; - - cycles -= voodoo->read_time; - - if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ - { - if (SLI_ENABLED) - { - voodoo_set_t *set = voodoo->set; - int y = (addr >> 11) & 0x3ff; - - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; - } - - voodoo->flush = 1; - while (!FIFO_EMPTY) - { - wake_fifo_thread_now(voodoo); - thread_wait_event(voodoo->fifo_not_full_event, 1); - } - wait_for_render_thread_idle(voodoo); - voodoo->flush = 0; - - return voodoo_fb_readw(addr, voodoo); - } - - return 0xffff; -} - -static void voodoo_flush(voodoo_t *voodoo) -{ - voodoo->flush = 1; - while (!FIFO_EMPTY) - { - wake_fifo_thread_now(voodoo); - thread_wait_event(voodoo->fifo_not_full_event, 1); - } - wait_for_render_thread_idle(voodoo); - voodoo->flush = 0; -} - -static void wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo) -{ - wake_fifo_thread(voodoo); - if (SLI_ENABLED && voodoo->type != VOODOO_2 && set->voodoos[0] == voodoo) - wake_fifo_thread(set->voodoos[1]); -} - -static uint32_t voodoo_readl(uint32_t addr, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - uint32_t temp = 0; - int fifo_size; - voodoo->rd_count++; - addr &= 0xffffff; - - cycles -= voodoo->read_time; - - if (addr & 0x800000) /*Texture*/ - { - } - else if (addr & 0x400000) /*Framebuffer*/ - { - if (SLI_ENABLED) - { - voodoo_set_t *set = voodoo->set; - int y = (addr >> 11) & 0x3ff; - - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; - } - - voodoo->flush = 1; - while (!FIFO_EMPTY) - { - wake_fifo_thread_now(voodoo); - thread_wait_event(voodoo->fifo_not_full_event, 1); - } - wait_for_render_thread_idle(voodoo); - voodoo->flush = 0; - - temp = voodoo_fb_readl(addr, voodoo); - } - else switch (addr & 0x3fc) - { - case SST_status: - { - int fifo_entries = FIFO_ENTRIES; - int swap_count = voodoo->swap_count; - int written = voodoo->cmd_written + voodoo->cmd_written_fifo; - int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr); - - if (SLI_ENABLED && voodoo->type != VOODOO_2) - { - voodoo_t *voodoo_other = (voodoo == voodoo->set->voodoos[0]) ? voodoo->set->voodoos[1] : voodoo->set->voodoos[0]; - int other_written = voodoo_other->cmd_written + voodoo_other->cmd_written_fifo; - - if (voodoo_other->swap_count > swap_count) - swap_count = voodoo_other->swap_count; - if ((voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx) > fifo_entries) - fifo_entries = voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx; - if ((other_written - voodoo_other->cmd_read) || - (voodoo_other->cmdfifo_depth_rd != voodoo_other->cmdfifo_depth_wr)) - busy = 1; - if (!voodoo_other->voodoo_busy) - wake_fifo_thread(voodoo_other); - } - - fifo_size = 0xffff - fifo_entries; - temp = fifo_size << 12; - if (fifo_size < 0x40) - temp |= fifo_size; - else - temp |= 0x3f; - if (swap_count < 7) - temp |= (swap_count << 28); - else - temp |= (7 << 28); - if (!voodoo->v_retrace) - temp |= 0x40; - - if (busy) - temp |= 0x380; /*Busy*/ - - if (!voodoo->voodoo_busy) - wake_fifo_thread(voodoo); - } - break; - - case SST_fbzColorPath: - voodoo_flush(voodoo); - temp = voodoo->params.fbzColorPath; - break; - case SST_fogMode: - voodoo_flush(voodoo); - temp = voodoo->params.fogMode; - break; - case SST_alphaMode: - voodoo_flush(voodoo); - temp = voodoo->params.alphaMode; - break; - case SST_fbzMode: - voodoo_flush(voodoo); - temp = voodoo->params.fbzMode; - break; - case SST_lfbMode: - voodoo_flush(voodoo); - temp = voodoo->lfbMode; - break; - case SST_clipLeftRight: - voodoo_flush(voodoo); - temp = voodoo->params.clipRight | (voodoo->params.clipLeft << 16); - break; - case SST_clipLowYHighY: - voodoo_flush(voodoo); - temp = voodoo->params.clipHighY | (voodoo->params.clipLowY << 16); - break; - - case SST_stipple: - voodoo_flush(voodoo); - temp = voodoo->params.stipple; - break; - case SST_color0: - voodoo_flush(voodoo); - temp = voodoo->params.color0; - break; - case SST_color1: - voodoo_flush(voodoo); - temp = voodoo->params.color1; - break; - - case SST_fbiPixelsIn: - temp = voodoo->fbiPixelsIn & 0xffffff; - break; - case SST_fbiChromaFail: - temp = voodoo->fbiChromaFail & 0xffffff; - break; - case SST_fbiZFuncFail: - temp = voodoo->fbiZFuncFail & 0xffffff; - break; - case SST_fbiAFuncFail: - temp = voodoo->fbiAFuncFail & 0xffffff; - break; - case SST_fbiPixelsOut: - temp = voodoo->fbiPixelsOut & 0xffffff; - break; - - case SST_fbiInit4: - temp = voodoo->fbiInit4; - break; - case SST_fbiInit0: - temp = voodoo->fbiInit0; - break; - case SST_fbiInit1: - temp = voodoo->fbiInit1; - break; - case SST_fbiInit2: - if (voodoo->initEnable & 0x04) - temp = voodoo->dac_readdata; - else - temp = voodoo->fbiInit2; - break; - case SST_fbiInit3: - temp = voodoo->fbiInit3 | (1 << 10) | (2 << 8); - break; - - case SST_vRetrace: - timer_clock(); - temp = voodoo->line & 0x1fff; - break; - case SST_hvRetrace: - timer_clock(); - temp = voodoo->line & 0x1fff; - temp |= ((((voodoo->line_time - voodoo->timer_count) * voodoo->h_total) / voodoo->timer_count) << 16) & 0x7ff0000; - break; - - case SST_fbiInit5: - temp = voodoo->fbiInit5 & ~0x1ff; - break; - case SST_fbiInit6: - temp = voodoo->fbiInit6; - break; - case SST_fbiInit7: - temp = voodoo->fbiInit7 & ~0xff; - break; - - case SST_cmdFifoBaseAddr: - temp = voodoo->cmdfifo_base >> 12; - temp |= (voodoo->cmdfifo_end >> 12) << 16; - break; - - case SST_cmdFifoRdPtr: - temp = voodoo->cmdfifo_rp; - break; - case SST_cmdFifoAMin: - temp = voodoo->cmdfifo_amin; - break; - case SST_cmdFifoAMax: - temp = voodoo->cmdfifo_amax; - break; - case SST_cmdFifoDepth: - temp = voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd; - break; - - default: - fatal("voodoo_readl : bad addr %08X\n", addr); - temp = 0xffffffff; - } - - return temp; -} - -static void voodoo_writew(uint32_t addr, uint16_t val, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - voodoo->wr_count++; - addr &= 0xffffff; - - if (addr == voodoo->last_write_addr+4) - cycles -= voodoo->burst_time; - else - cycles -= voodoo->write_time; - voodoo->last_write_addr = addr; - - if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ - queue_command(voodoo, addr | FIFO_WRITEW_FB, val); -} - -static void voodoo_pixelclock_update(voodoo_t *voodoo) -{ - int m = (voodoo->dac_pll_regs[0] & 0x7f) + 2; - int n1 = ((voodoo->dac_pll_regs[0] >> 8) & 0x1f) + 2; - int n2 = ((voodoo->dac_pll_regs[0] >> 13) & 0x07); - float t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); - double clock_const; - int line_length; - - if ((voodoo->dac_data[6] & 0xf0) == 0x20 || - (voodoo->dac_data[6] & 0xf0) == 0x60 || - (voodoo->dac_data[6] & 0xf0) == 0x70) - t /= 2.0f; - - line_length = (voodoo->hSync & 0xff) + ((voodoo->hSync >> 16) & 0x3ff); - -// voodoo_log("Pixel clock %f MHz hsync %08x line_length %d\n", t, voodoo->hSync, line_length); - - voodoo->pixel_clock = t; - - clock_const = cpuclock / t; - voodoo->line_time = (int)((double)line_length * clock_const * (double)(1 << TIMER_SHIFT)); -} - -static void voodoo_writel(uint32_t addr, uint32_t val, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - - voodoo->wr_count++; - - addr &= 0xffffff; - - if (addr == voodoo->last_write_addr+4) - cycles -= voodoo->burst_time; - else - cycles -= voodoo->write_time; - voodoo->last_write_addr = addr; - - if (addr & 0x800000) /*Texture*/ - { - voodoo->tex_count++; - queue_command(voodoo, addr | FIFO_WRITEL_TEX, val); - } - else if (addr & 0x400000) /*Framebuffer*/ - { - queue_command(voodoo, addr | FIFO_WRITEL_FB, val); - } - else if ((addr & 0x200000) && (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)) - { -// voodoo_log("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask); - *(uint32_t *)&voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val; - voodoo->cmdfifo_depth_wr++; - if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) - wake_fifo_thread(voodoo); - } - else switch (addr & 0x3fc) - { - case SST_intrCtrl: - fatal("intrCtrl write %08x\n", val); - break; - - case SST_userIntrCMD: - fatal("userIntrCMD write %08x\n", val); - break; - - case SST_swapbufferCMD: - voodoo->cmd_written++; - voodoo->swap_count++; - if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; - queue_command(voodoo, addr | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_triangleCMD: - if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; - voodoo->cmd_written++; - queue_command(voodoo, addr | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_ftriangleCMD: - if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; - voodoo->cmd_written++; - queue_command(voodoo, addr | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_fastfillCMD: - if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; - voodoo->cmd_written++; - queue_command(voodoo, addr | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_nopCMD: - if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; - voodoo->cmd_written++; - queue_command(voodoo, addr | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - wake_fifo_threads(voodoo->set, voodoo); - break; - - case SST_fbiInit4: - if (voodoo->initEnable & 0x01) - { - voodoo->fbiInit4 = val; - voodoo->read_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit4 & 1) ? 2 : 1); -// voodoo_log("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time); - } - break; - case SST_backPorch: - voodoo->backPorch = val; - break; - case SST_videoDimensions: - voodoo->videoDimensions = val; - voodoo->h_disp = (val & 0xfff) + 1; - voodoo->v_disp = (val >> 16) & 0xfff; - break; - case SST_fbiInit0: - if (voodoo->initEnable & 0x01) - { - voodoo->fbiInit0 = val; - if (voodoo->set->nr_cards == 2) - svga_set_override(voodoo->svga, (voodoo->set->voodoos[0]->fbiInit0 | voodoo->set->voodoos[1]->fbiInit0) & 1); - else - svga_set_override(voodoo->svga, val & 1); - if (val & FBIINIT0_GRAPHICS_RESET) - { - /*Reset display/draw buffer selection. This may not actually - happen here on a real Voodoo*/ - voodoo->disp_buffer = 0; - voodoo->draw_buffer = 1; - voodoo_recalc(voodoo); - voodoo->front_offset = voodoo->params.front_offset; - } - } - break; - case SST_fbiInit1: - if (voodoo->initEnable & 0x01) - { - if ((voodoo->fbiInit1 & FBIINIT1_VIDEO_RESET) && !(val & FBIINIT1_VIDEO_RESET)) - { - voodoo->line = 0; - voodoo->swap_count = 0; - voodoo->retrace_count = 0; - } - voodoo->fbiInit1 = (val & ~5) | (voodoo->fbiInit1 & 5); - voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0); - voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1); -// voodoo_log("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time); - } - break; - case SST_fbiInit2: - if (voodoo->initEnable & 0x01) - { - voodoo->fbiInit2 = val; - voodoo_recalc(voodoo); - } - break; - case SST_fbiInit3: - if (voodoo->initEnable & 0x01) - voodoo->fbiInit3 = val; - break; - - case SST_hSync: - voodoo->hSync = val; - voodoo->h_total = (val & 0xffff) + (val >> 16); - voodoo_pixelclock_update(voodoo); - break; - case SST_vSync: - voodoo->vSync = val; - voodoo->v_total = (val & 0xffff) + (val >> 16); - break; - - case SST_clutData: - voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; - voodoo->clutData[(val >> 24) & 0x3f].g = (val >> 8) & 0xff; - voodoo->clutData[(val >> 24) & 0x3f].r = (val >> 16) & 0xff; - if (val & 0x20000000) - { - voodoo->clutData[(val >> 24) & 0x3f].b = 255; - voodoo->clutData[(val >> 24) & 0x3f].g = 255; - voodoo->clutData[(val >> 24) & 0x3f].r = 255; - } - voodoo->clutData_dirty = 1; - break; - - case SST_dacData: - voodoo->dac_reg = (val >> 8) & 7; - voodoo->dac_readdata = 0xff; - if (val & 0x800) - { -// voodoo_log(" dacData read %i %02X\n", voodoo->dac_reg, voodoo->dac_data[7]); - if (voodoo->dac_reg == 5) - { - switch (voodoo->dac_data[7]) - { - case 0x01: voodoo->dac_readdata = 0x55; break; - case 0x07: voodoo->dac_readdata = 0x71; break; - case 0x0b: voodoo->dac_readdata = 0x79; break; - } - } - else - voodoo->dac_readdata = voodoo->dac_data[voodoo->dac_readdata & 7]; - } - else - { - if (voodoo->dac_reg == 5) - { - if (!voodoo->dac_reg_ff) - voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff00) | val; - else - voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff) | (val << 8); -// voodoo_log("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]); - voodoo->dac_reg_ff = !voodoo->dac_reg_ff; - if (!voodoo->dac_reg_ff) - voodoo->dac_data[4]++; - - } - else - { - voodoo->dac_data[voodoo->dac_reg] = val & 0xff; - voodoo->dac_reg_ff = 0; - } - voodoo_pixelclock_update(voodoo); - } - break; - - case SST_scrFilter: - if (voodoo->initEnable & 0x01) - { - voodoo->scrfilterEnabled = 1; - voodoo->scrfilterThreshold = val; /* update the threshold values and generate a new lookup table if necessary */ - - if (val < 1) - voodoo->scrfilterEnabled = 0; - voodoo_threshold_check(voodoo); - voodoo_log("Voodoo Filter: %06x\n", val); - } - break; - - case SST_fbiInit5: - if (voodoo->initEnable & 0x01) - voodoo->fbiInit5 = (val & ~0x41e6) | (voodoo->fbiInit5 & 0x41e6); - break; - case SST_fbiInit6: - if (voodoo->initEnable & 0x01) - voodoo->fbiInit6 = val; - break; - case SST_fbiInit7: - if (voodoo->initEnable & 0x01) - voodoo->fbiInit7 = val; - break; - - case SST_cmdFifoBaseAddr: - voodoo->cmdfifo_base = (val & 0x3ff) << 12; - voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; -// voodoo_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); - break; - - case SST_cmdFifoRdPtr: - voodoo->cmdfifo_rp = val; - break; - case SST_cmdFifoAMin: - voodoo->cmdfifo_amin = val; - break; - case SST_cmdFifoAMax: - voodoo->cmdfifo_amax = val; - break; - case SST_cmdFifoDepth: - voodoo->cmdfifo_depth_rd = 0; - voodoo->cmdfifo_depth_wr = val & 0xffff; - break; - - default: - if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - { - voodoo_log("Unknown register write in CMDFIFO mode %08x %08x\n", addr, val); - } - else - { - queue_command(voodoo, addr | FIFO_WRITEL_REG, val); - } - break; - } -} - -static uint16_t voodoo_snoop_readw(uint32_t addr, void *p) -{ - voodoo_set_t *set = (voodoo_set_t *)p; - - return voodoo_readw(addr, set->voodoos[0]); -} -static uint32_t voodoo_snoop_readl(uint32_t addr, void *p) -{ - voodoo_set_t *set = (voodoo_set_t *)p; - - return voodoo_readl(addr, set->voodoos[0]); -} - -static void voodoo_snoop_writew(uint32_t addr, uint16_t val, void *p) -{ - voodoo_set_t *set = (voodoo_set_t *)p; - - voodoo_writew(addr, val, set->voodoos[0]); - voodoo_writew(addr, val, set->voodoos[1]); -} -static void voodoo_snoop_writel(uint32_t addr, uint32_t val, void *p) -{ - voodoo_set_t *set = (voodoo_set_t *)p; - - voodoo_writel(addr, val, set->voodoos[0]); - voodoo_writel(addr, val, set->voodoos[1]); -} - -static uint32_t cmdfifo_get(voodoo_t *voodoo) -{ - uint32_t val; - - while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr) - { - thread_wait_event(voodoo->wake_fifo_thread, -1); - thread_reset_event(voodoo->wake_fifo_thread); - } - - val = *(uint32_t *)&voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask]; - - voodoo->cmdfifo_depth_rd++; - voodoo->cmdfifo_rp += 4; - -// voodoo_log(" CMDFIFO get %08x\n", val); - return val; -} - -static inline float cmdfifo_get_f(voodoo_t *voodoo) -{ - union - { - uint32_t i; - float f; - } tempif; - - tempif.i = cmdfifo_get(voodoo); - return tempif.f; -} - -enum -{ - CMDFIFO3_PC_MASK_RGB = (1 << 10), - CMDFIFO3_PC_MASK_ALPHA = (1 << 11), - CMDFIFO3_PC_MASK_Z = (1 << 12), - CMDFIFO3_PC_MASK_Wb = (1 << 13), - CMDFIFO3_PC_MASK_W0 = (1 << 14), - CMDFIFO3_PC_MASK_S0_T0 = (1 << 15), - CMDFIFO3_PC_MASK_W1 = (1 << 16), - CMDFIFO3_PC_MASK_S1_T1 = (1 << 17), - - CMDFIFO3_PC = (1 << 28) -}; - -static void fifo_thread(void *param) -{ - voodoo_t *voodoo = (voodoo_t *)param; - - while (1) - { - thread_set_event(voodoo->fifo_not_full_event); - thread_wait_event(voodoo->wake_fifo_thread, -1); - thread_reset_event(voodoo->wake_fifo_thread); - voodoo->voodoo_busy = 1; - while (!FIFO_EMPTY) - { - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - - switch (fifo->addr_type & FIFO_TYPE) - { - case FIFO_WRITEL_REG: - voodoo_reg_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - break; - case FIFO_WRITEW_FB: - wait_for_render_thread_idle(voodoo); - voodoo_fb_writew(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - break; - case FIFO_WRITEL_FB: - wait_for_render_thread_idle(voodoo); - voodoo_fb_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - break; - case FIFO_WRITEL_TEX: - if (!(fifo->addr_type & 0x400000)) - voodoo_tex_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - break; - } - voodoo->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; - - if (FIFO_ENTRIES > 0xe000) - thread_set_event(voodoo->fifo_not_full_event); - - end_time = plat_timer_read(); - voodoo->time += end_time - start_time; - } - - while (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) - { - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - uint32_t header = cmdfifo_get(voodoo); - uint32_t addr; - uint32_t mask; - int smode; - int num; - int num_verticies; - int v_num; - -// voodoo_log(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp); - - switch (header & 7) - { - case 0: -// voodoo_log("CMDFIFO0\n"); - switch ((header >> 3) & 7) - { - case 0: /*NOP*/ - break; - - case 3: /*JMP local frame buffer*/ - voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; -// voodoo_log("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header); - break; - - default: - fatal("Bad CMDFIFO0 %08x\n", header); - } - break; - - case 1: - num = header >> 16; - addr = (header & 0x7ff8) >> 1; -// voodoo_log("CMDFIFO1 addr=%08x\n",addr); - while (num--) - { - uint32_t val = cmdfifo_get(voodoo); - if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || - (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) - voodoo->cmd_written_fifo++; - - voodoo_reg_writel(addr, val, voodoo); - - if (header & (1 << 15)) - addr += 4; - } - break; - - case 3: - num = (header >> 29) & 7; - mask = header;//(header >> 10) & 0xff; - smode = (header >> 22) & 0xf; - voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo); - num_verticies = (header >> 6) & 0xf; - v_num = 0; - if (((header >> 3) & 7) == 2) - v_num = 1; -// voodoo_log("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, num_verticies, (header >> 10) & 0xff); -// voodoo_log("CMDFIFO3 %02x %i\n", (header >> 10), (header >> 3) & 7); - - while (num_verticies--) - { - voodoo->verts[3].sVx = cmdfifo_get_f(voodoo); - voodoo->verts[3].sVy = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_RGB) - { - if (header & CMDFIFO3_PC) - { - uint32_t val = cmdfifo_get(voodoo); - voodoo->verts[3].sBlue = (float)(val & 0xff); - voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff); - voodoo->verts[3].sRed = (float)((val >> 16) & 0xff); - voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff); - } - else - { - voodoo->verts[3].sRed = cmdfifo_get_f(voodoo); - voodoo->verts[3].sGreen = cmdfifo_get_f(voodoo); - voodoo->verts[3].sBlue = cmdfifo_get_f(voodoo); - } - } - if ((mask & CMDFIFO3_PC_MASK_ALPHA) && !(header & CMDFIFO3_PC)) - voodoo->verts[3].sAlpha = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_Z) - voodoo->verts[3].sVz = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_Wb) - voodoo->verts[3].sWb = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_W0) - voodoo->verts[3].sW0 = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_S0_T0) - { - voodoo->verts[3].sS0 = cmdfifo_get_f(voodoo); - voodoo->verts[3].sT0 = cmdfifo_get_f(voodoo); - } - if (mask & CMDFIFO3_PC_MASK_W1) - voodoo->verts[3].sW1 = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_S1_T1) - { - voodoo->verts[3].sS1 = cmdfifo_get_f(voodoo); - voodoo->verts[3].sT1 = cmdfifo_get_f(voodoo); - } - if (v_num) - voodoo_reg_writel(SST_sDrawTriCMD, 0, voodoo); - else - voodoo_reg_writel(SST_sBeginTriCMD, 0, voodoo); - v_num++; - if (v_num == 3 && ((header >> 3) & 7) == 0) - v_num = 0; - } - break; - - case 4: - num = (header >> 29) & 7; - mask = (header >> 15) & 0x3fff; - addr = (header & 0x7ff8) >> 1; -// voodoo_log("CMDFIFO4 addr=%08x\n",addr); - while (mask) - { - if (mask & 1) - { - uint32_t val = cmdfifo_get(voodoo); - if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || - (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) - voodoo->cmd_written_fifo++; - - voodoo_reg_writel(addr, val, voodoo); - } - - addr += 4; - mask >>= 1; - } - while (num--) - cmdfifo_get(voodoo); - break; - - case 5: - if (header & 0x3fc0000) - fatal("CMDFIFO packet 5 has byte disables set %08x\n", header); - num = (header >> 3) & 0x7ffff; - addr = cmdfifo_get(voodoo) & 0xffffff; -// voodoo_log("CMDFIFO5 addr=%08x num=%i\n", addr, num); - switch (header >> 30) - { - case 2: /*Framebuffer*/ - while (num--) - { - uint32_t val = cmdfifo_get(voodoo); - voodoo_fb_writel(addr, val, voodoo); - addr += 4; - } - break; - case 3: /*Texture*/ - while (num--) - { - uint32_t val = cmdfifo_get(voodoo); - voodoo_tex_writel(addr, val, voodoo); - addr += 4; - } - break; - - default: - fatal("CMDFIFO packet 5 bad space %08x %08x\n", header, voodoo->cmdfifo_rp); - } - break; - - default: - voodoo_log("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); - } - - end_time = plat_timer_read(); - voodoo->time += end_time - start_time; - } - voodoo->voodoo_busy = 0; - } -} - -static void voodoo_recalcmapping(voodoo_set_t *set) -{ - if (set->nr_cards == 2) - { - if (set->voodoos[0]->pci_enable && set->voodoos[0]->memBaseAddr) - { - if (set->voodoos[0]->type == VOODOO_2 && set->voodoos[1]->initEnable & (1 << 23)) - { - voodoo_log("voodoo_recalcmapping (pri) with snoop : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); - mem_mapping_disable(&set->voodoos[0]->mapping); - mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000); - } - else if (set->voodoos[1]->pci_enable && (set->voodoos[0]->memBaseAddr == set->voodoos[1]->memBaseAddr)) - { - voodoo_log("voodoo_recalcmapping (pri) (sec) same addr : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); - mem_mapping_disable(&set->voodoos[0]->mapping); - mem_mapping_disable(&set->voodoos[1]->mapping); - mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000); - return; - } - else - { - voodoo_log("voodoo_recalcmapping (pri) : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); - mem_mapping_disable(&set->snoop_mapping); - mem_mapping_set_addr(&set->voodoos[0]->mapping, set->voodoos[0]->memBaseAddr, 0x01000000); - } - } - else - { - voodoo_log("voodoo_recalcmapping (pri) : disabled\n"); - mem_mapping_disable(&set->voodoos[0]->mapping); - } - - if (set->voodoos[1]->pci_enable && set->voodoos[1]->memBaseAddr) - { - voodoo_log("voodoo_recalcmapping (sec) : memBaseAddr %08X\n", set->voodoos[1]->memBaseAddr); - mem_mapping_set_addr(&set->voodoos[1]->mapping, set->voodoos[1]->memBaseAddr, 0x01000000); - } - else - { - voodoo_log("voodoo_recalcmapping (sec) : disabled\n"); - mem_mapping_disable(&set->voodoos[1]->mapping); - } - } - else - { - voodoo_t *voodoo = set->voodoos[0]; - - if (voodoo->pci_enable && voodoo->memBaseAddr) - { - voodoo_log("voodoo_recalcmapping : memBaseAddr %08X\n", voodoo->memBaseAddr); - mem_mapping_set_addr(&voodoo->mapping, voodoo->memBaseAddr, 0x01000000); - } - else - { - voodoo_log("voodoo_recalcmapping : disabled\n"); - mem_mapping_disable(&voodoo->mapping); - } - } -} - -uint8_t voodoo_pci_read(int func, int addr, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - - if (func) - return 0; - -// voodoo_log("Voodoo PCI read %08X PC=%08x\n", addr, cpu_state.pc); - - switch (addr) - { - case 0x00: return 0x1a; /*3dfx*/ - case 0x01: return 0x12; - - case 0x02: - if (voodoo->type == VOODOO_2) - return 0x02; /*Voodoo 2*/ - else - return 0x01; /*SST-1 (Voodoo Graphics)*/ - case 0x03: return 0x00; - - case 0x04: return voodoo->pci_enable ? 0x02 : 0x00; /*Respond to memory accesses*/ - - case 0x08: return 2; /*Revision ID*/ - case 0x09: return 0; /*Programming interface*/ - case 0x0a: return 0; - case 0x0b: return 0x04; - - case 0x10: return 0x00; /*memBaseAddr*/ - case 0x11: return 0x00; - case 0x12: return 0x00; - case 0x13: return voodoo->memBaseAddr >> 24; - - case 0x40: - return voodoo->initEnable & 0xff; - case 0x41: - if (voodoo->type == VOODOO_2) - return 0x50 | ((voodoo->initEnable >> 8) & 0x0f); - return (voodoo->initEnable >> 8) & 0x0f; - case 0x42: - return (voodoo->initEnable >> 16) & 0xff; - case 0x43: - return (voodoo->initEnable >> 24) & 0xff; - } - return 0; -} - -void voodoo_pci_write(int func, int addr, uint8_t val, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - - if (func) - return; - -// voodoo_log("Voodoo PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); - - switch (addr) - { - case 0x04: - voodoo->pci_enable = val & 2; - voodoo_recalcmapping(voodoo->set); - break; - - case 0x13: - voodoo->memBaseAddr = val << 24; - voodoo_recalcmapping(voodoo->set); - break; - - case 0x40: - voodoo->initEnable = (voodoo->initEnable & ~0x000000ff) | val; - break; - case 0x41: - voodoo->initEnable = (voodoo->initEnable & ~0x0000ff00) | (val << 8); - break; - case 0x42: - voodoo->initEnable = (voodoo->initEnable & ~0x00ff0000) | (val << 16); - voodoo_recalcmapping(voodoo->set); - break; - case 0x43: - voodoo->initEnable = (voodoo->initEnable & ~0xff000000) | (val << 24); - voodoo_recalcmapping(voodoo->set); - break; - } -} - -static void voodoo_calc_clutData(voodoo_t *voodoo) -{ - int c; - - for (c = 0; c < 256; c++) - { - voodoo->clutData256[c].r = (voodoo->clutData[c >> 3].r*(8-(c & 7)) + - voodoo->clutData[(c >> 3)+1].r*(c & 7)) >> 3; - voodoo->clutData256[c].g = (voodoo->clutData[c >> 3].g*(8-(c & 7)) + - voodoo->clutData[(c >> 3)+1].g*(c & 7)) >> 3; - voodoo->clutData256[c].b = (voodoo->clutData[c >> 3].b*(8-(c & 7)) + - voodoo->clutData[(c >> 3)+1].b*(c & 7)) >> 3; - } - - for (c = 0; c < 65536; c++) - { - int r = (c >> 8) & 0xf8; - int g = (c >> 3) & 0xfc; - int b = (c << 3) & 0xf8; -// r |= (r >> 5); -// g |= (g >> 6); -// b |= (b >> 5); - - voodoo->video_16to32[c] = (voodoo->clutData256[r].r << 16) | (voodoo->clutData256[g].g << 8) | voodoo->clutData256[b].b; - } -} - - - -#define FILTDIV 256 - -static int FILTCAP, FILTCAPG, FILTCAPB = 0; /* color filter threshold values */ - -static void voodoo_generate_filter_v1(voodoo_t *voodoo) -{ - int g, h; - float difference, diffg, diffb; - float thiscol, thiscolg, thiscolb, lined; - float fcr, fcg, fcb; - - fcr = FILTCAP * 5; - fcg = FILTCAPG * 6; - fcb = FILTCAPB * 5; - - for (g=0;g FILTCAP) - difference = FILTCAP; - if (difference < -FILTCAP) - difference = -FILTCAP; - - if (diffg > FILTCAPG) - diffg = FILTCAPG; - if (diffg < -FILTCAPG) - diffg = -FILTCAPG; - - if (diffb > FILTCAPB) - diffb = FILTCAPB; - if (diffb < -FILTCAPB) - diffb = -FILTCAPB; - - // hack - to make it not bleed onto black - //if (g == 0){ - //difference = diffg = diffb = 0; - //} - - if ((difference < fcr) || (-difference > -fcr)) - thiscol = g + (difference / 2); - if ((diffg < fcg) || (-diffg > -fcg)) - thiscolg = g + (diffg / 2); /* need these divides so we can actually undither! */ - if ((diffb < fcb) || (-diffb > -fcb)) - thiscolb = g + (diffb / 2); - - if (thiscol < 0) - thiscol = 0; - if (thiscol > FILTDIV-1) - thiscol = FILTDIV-1; - - if (thiscolg < 0) - thiscolg = 0; - if (thiscolg > FILTDIV-1) - thiscolg = FILTDIV-1; - - if (thiscolb < 0) - thiscolb = 0; - if (thiscolb > FILTDIV-1) - thiscolb = FILTDIV-1; - - voodoo->thefilter[g][h] = thiscol; - voodoo->thefilterg[g][h] = thiscolg; - voodoo->thefilterb[g][h] = thiscolb; - } - - lined = g + 4; - if (lined > 255) - lined = 255; - voodoo->purpleline[g][0] = lined; - voodoo->purpleline[g][2] = lined; - - lined = g + 0; - if (lined > 255) - lined = 255; - voodoo->purpleline[g][1] = lined; - } -} - -static void voodoo_generate_filter_v2(voodoo_t *voodoo) -{ - int g, h; - float difference; - float thiscol, thiscolg, thiscolb, lined; - float clr, clg, clb = 0; - float fcr, fcg, fcb = 0; - - // pre-clamping - - fcr = FILTCAP; - fcg = FILTCAPG; - fcb = FILTCAPB; - - if (fcr > 32) fcr = 32; - if (fcg > 32) fcg = 32; - if (fcb > 32) fcb = 32; - - for (g=0;g<256;g++) // pixel 1 - our target pixel we want to bleed into - { - for (h=0;h<256;h++) // pixel 2 - our main pixel - { - float avg; - float avgdiff; - - difference = (float)(g - h); - avg = (float)((g + g + g + g + h) / 5); - avgdiff = avg - (float)((g + h + h + h + h) / 5); - if (avgdiff < 0) avgdiff *= -1; - if (difference < 0) difference *= -1; - - thiscol = thiscolg = thiscolb = g; - - // try lighten - if (h > g) - { - clr = clg = clb = avgdiff; - - if (clr>fcr) clr=fcr; - if (clg>fcg) clg=fcg; - if (clb>fcb) clb=fcb; - - - thiscol = g + clr; - thiscolg = g + clg; - thiscolb = g + clb; - - if (thiscol>g+FILTCAP) - thiscol=g+FILTCAP; - if (thiscolg>g+FILTCAPG) - thiscolg=g+FILTCAPG; - if (thiscolb>g+FILTCAPB) - thiscolb=g+FILTCAPB; - - - if (thiscol>g+avgdiff) - thiscol=g+avgdiff; - if (thiscolg>g+avgdiff) - thiscolg=g+avgdiff; - if (thiscolb>g+avgdiff) - thiscolb=g+avgdiff; - - } - - if (difference > FILTCAP) - thiscol = g; - if (difference > FILTCAPG) - thiscolg = g; - if (difference > FILTCAPB) - thiscolb = g; - - // clamp - if (thiscol < 0) thiscol = 0; - if (thiscolg < 0) thiscolg = 0; - if (thiscolb < 0) thiscolb = 0; - - if (thiscol > 255) thiscol = 255; - if (thiscolg > 255) thiscolg = 255; - if (thiscolb > 255) thiscolb = 255; - - // add to the table - voodoo->thefilter[g][h] = (thiscol); - voodoo->thefilterg[g][h] = (thiscolg); - voodoo->thefilterb[g][h] = (thiscolb); - - // debug the ones that don't give us much of a difference - //if (difference < FILTCAP) - //voodoo_log("Voodoofilter: %ix%i - %f difference, %f average difference, R=%f, G=%f, B=%f\n", g, h, difference, avgdiff, thiscol, thiscolg, thiscolb); - } - - lined = g + 3; - if (lined > 255) - lined = 255; - voodoo->purpleline[g][0] = lined; - voodoo->purpleline[g][1] = 0; - voodoo->purpleline[g][2] = lined; - } -} - -static void voodoo_threshold_check(voodoo_t *voodoo) -{ - int r, g, b; - - if (!voodoo->scrfilterEnabled) - return; /* considered disabled; don't check and generate */ - - /* Check for changes, to generate anew table */ - if (voodoo->scrfilterThreshold != voodoo->scrfilterThresholdOld) - { - r = (voodoo->scrfilterThreshold >> 16) & 0xFF; - g = (voodoo->scrfilterThreshold >> 8 ) & 0xFF; - b = voodoo->scrfilterThreshold & 0xFF; - - FILTCAP = r; - FILTCAPG = g; - FILTCAPB = b; - - voodoo_log("Voodoo Filter Threshold Check: %06x - RED %i GREEN %i BLUE %i\n", voodoo->scrfilterThreshold, r, g, b); - - voodoo->scrfilterThresholdOld = voodoo->scrfilterThreshold; - - if (voodoo->type == VOODOO_2) - voodoo_generate_filter_v2(voodoo); - else - voodoo_generate_filter_v1(voodoo); - } -} - -static void voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) -{ - int x; - - // Scratchpad for avoiding feedback streaks - uint8_t fil3[(voodoo->h_disp) * 3]; - - /* 16 to 32-bit */ - for (x=0; x> 5) & 63) << 2); - fil[x*3+2] = (((src[x] >> 11) & 31) << 3); - - // Copy to our scratchpads - fil3[x*3+0] = fil[x*3+0]; - fil3[x*3+1] = fil[x*3+1]; - fil3[x*3+2] = fil[x*3+2]; - } - - - /* lines */ - - if (line & 1) - { - for (x=0; xpurpleline[fil[x*3]][0]; - fil[x*3+1] = voodoo->purpleline[fil[x*3+1]][1]; - fil[x*3+2] = voodoo->purpleline[fil[x*3+2]][2]; - } - } - - - /* filtering time */ - - for (x=1; xthefilterb[fil[x*3]][fil[ (x-1) *3]]; - fil3[(x)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]]; - fil3[(x)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]]; - } - - for (x=1; xthefilterb[fil3[x*3]][fil3[ (x-1) *3]]; - fil[(x)*3+1] = voodoo->thefilterg[fil3[x*3+1]][fil3[ (x-1) *3+1]]; - fil[(x)*3+2] = voodoo->thefilter[fil3[x*3+2]][fil3[ (x-1) *3+2]]; - } - - for (x=1; xthefilterb[fil[x*3]][fil[ (x-1) *3]]; - fil3[(x)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]]; - fil3[(x)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]]; - } - - for (x=0; xthefilterb[fil3[x*3]][fil3[ (x+1) *3]]; - fil[(x)*3+1] = voodoo->thefilterg[fil3[x*3+1]][fil3[ (x+1) *3+1]]; - fil[(x)*3+2] = voodoo->thefilter[fil3[x*3+2]][fil3[ (x+1) *3+2]]; - } -} - - -static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) -{ - int x; - - // Scratchpad for blending filter - uint8_t fil3[(voodoo->h_disp) * 3]; - - /* 16 to 32-bit */ - for (x=0; x> 5) & 63) << 2); - fil3[x*3+2] = fil[x*3+2] = (((src[x] >> 11) & 31) << 3); - } - - /* filtering time */ - - for (x=1; xthefilterb [((src[x+3] & 31) << 3)] [((src[x] & 31) << 3)]; - fil3[(x+3)*3+1] = voodoo->thefilterg [(((src[x+3] >> 5) & 63) << 2)] [(((src[x] >> 5) & 63) << 2)]; - fil3[(x+3)*3+2] = voodoo->thefilter [(((src[x+3] >> 11) & 31) << 3)] [(((src[x] >> 11) & 31) << 3)]; - - fil[(x+2)*3] = voodoo->thefilterb [fil3[(x+2)*3]][((src[x] & 31) << 3)]; - fil[(x+2)*3+1] = voodoo->thefilterg [fil3[(x+2)*3+1]][(((src[x] >> 5) & 63) << 2)]; - fil[(x+2)*3+2] = voodoo->thefilter [fil3[(x+2)*3+2]][(((src[x] >> 11) & 31) << 3)]; - - fil3[(x+1)*3] = voodoo->thefilterb [fil[(x+1)*3]][((src[x] & 31) << 3)]; - fil3[(x+1)*3+1] = voodoo->thefilterg [fil[(x+1)*3+1]][(((src[x] >> 5) & 63) << 2)]; - fil3[(x+1)*3+2] = voodoo->thefilter [fil[(x+1)*3+2]][(((src[x] >> 11) & 31) << 3)]; - - fil[(x-1)*3] = voodoo->thefilterb [fil3[(x-1)*3]][((src[x] & 31) << 3)]; - fil[(x-1)*3+1] = voodoo->thefilterg [fil3[(x-1)*3+1]][(((src[x] >> 5) & 63) << 2)]; - fil[(x-1)*3+2] = voodoo->thefilter [fil3[(x-1)*3+2]][(((src[x] >> 11) & 31) << 3)]; - } - - // unroll for edge cases - - fil3[(column-3)*3] = voodoo->thefilterb [((src[column-3] & 31) << 3)] [((src[column] & 31) << 3)]; - fil3[(column-3)*3+1] = voodoo->thefilterg [(((src[column-3] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; - fil3[(column-3)*3+2] = voodoo->thefilter [(((src[column-3] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; - - fil3[(column-2)*3] = voodoo->thefilterb [((src[column-2] & 31) << 3)] [((src[column] & 31) << 3)]; - fil3[(column-2)*3+1] = voodoo->thefilterg [(((src[column-2] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; - fil3[(column-2)*3+2] = voodoo->thefilter [(((src[column-2] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; - - fil3[(column-1)*3] = voodoo->thefilterb [((src[column-1] & 31) << 3)] [((src[column] & 31) << 3)]; - fil3[(column-1)*3+1] = voodoo->thefilterg [(((src[column-1] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; - fil3[(column-1)*3+2] = voodoo->thefilter [(((src[column-1] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; - - fil[(column-2)*3] = voodoo->thefilterb [fil3[(column-2)*3]][((src[column] & 31) << 3)]; - fil[(column-2)*3+1] = voodoo->thefilterg [fil3[(column-2)*3+1]][(((src[column] >> 5) & 63) << 2)]; - fil[(column-2)*3+2] = voodoo->thefilter [fil3[(column-2)*3+2]][(((src[column] >> 11) & 31) << 3)]; - - fil[(column-1)*3] = voodoo->thefilterb [fil3[(column-1)*3]][((src[column] & 31) << 3)]; - fil[(column-1)*3+1] = voodoo->thefilterg [fil3[(column-1)*3+1]][(((src[column] >> 5) & 63) << 2)]; - fil[(column-1)*3+2] = voodoo->thefilter [fil3[(column-1)*3+2]][(((src[column] >> 11) & 31) << 3)]; - - fil3[(column-1)*3] = voodoo->thefilterb [fil[(column-1)*3]][((src[column] & 31) << 3)]; - fil3[(column-1)*3+1] = voodoo->thefilterg [fil[(column-1)*3+1]][(((src[column] >> 5) & 63) << 2)]; - fil3[(column-1)*3+2] = voodoo->thefilter [fil[(column-1)*3+2]][(((src[column] >> 11) & 31) << 3)]; -} - -void voodoo_callback(void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - int y_add = (enable_overscan && !suppress_overscan) ? (overscan_y >> 1) : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - - if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) - { - if (voodoo->line < voodoo->v_disp) - { - voodoo_t *draw_voodoo; - int draw_line; - - if (SLI_ENABLED) - { - if (voodoo == voodoo->set->voodoos[1]) - goto skip_draw; - - if (((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) ? 1 : 0) == (voodoo->line & 1)) - draw_voodoo = voodoo; - else - draw_voodoo = voodoo->set->voodoos[1]; - draw_line = voodoo->line >> 1; - } - else - { - if (!(voodoo->fbiInit0 & 1)) - goto skip_draw; - draw_voodoo = voodoo; - draw_line = voodoo->line; - } - - if (draw_voodoo->dirty_line[draw_line]) - { - uint32_t *p = &((uint32_t *)buffer32->line[voodoo->line + y_add])[32 + x_add]; - uint16_t *src = (uint16_t *)&draw_voodoo->fb_mem[draw_voodoo->front_offset + draw_line*draw_voodoo->row_width]; - int x; - - draw_voodoo->dirty_line[draw_line] = 0; - - if (voodoo->line < voodoo->dirty_line_low) - { - voodoo->dirty_line_low = voodoo->line; - video_wait_for_buffer(); - } - if (voodoo->line > voodoo->dirty_line_high) - voodoo->dirty_line_high = voodoo->line; - - if (voodoo->scrfilter && voodoo->scrfilterEnabled) - { - uint8_t fil[(voodoo->h_disp) * 3]; /* interleaved 24-bit RGB */ - - if (voodoo->type == VOODOO_2) - voodoo_filterline_v2(voodoo, fil, voodoo->h_disp, src, voodoo->line); - else - voodoo_filterline_v1(voodoo, fil, voodoo->h_disp, src, voodoo->line); - - for (x = 0; x < voodoo->h_disp; x++) - { - p[x] = (voodoo->clutData256[fil[x*3]].b << 0 | voodoo->clutData256[fil[x*3+1]].g << 8 | voodoo->clutData256[fil[x*3+2]].r << 16); - } - } - else - { - for (x = 0; x < voodoo->h_disp; x++) - { - p[x] = draw_voodoo->video_16to32[src[x]]; - } - } - } - } - } -skip_draw: - if (voodoo->line == voodoo->v_disp) - { -// voodoo_log("retrace %i %i %08x %i\n", voodoo->retrace_count, voodoo->swap_interval, voodoo->swap_offset, voodoo->swap_pending); - voodoo->retrace_count++; - if (SLI_ENABLED && (voodoo->fbiInit2 & FBIINIT2_SWAP_ALGORITHM_MASK) == FBIINIT2_SWAP_ALGORITHM_SLI_SYNC) - { - if (voodoo == voodoo->set->voodoos[0]) - { - voodoo_t *voodoo_1 = voodoo->set->voodoos[1]; - - /*Only swap if both Voodoos are waiting for buffer swap*/ - if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval) && - voodoo_1->swap_pending && (voodoo_1->retrace_count > voodoo_1->swap_interval)) - { - memset(voodoo->dirty_line, 1, 1024); - voodoo->retrace_count = 0; - voodoo->front_offset = voodoo->swap_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; - - memset(voodoo_1->dirty_line, 1, 1024); - voodoo_1->retrace_count = 0; - voodoo_1->front_offset = voodoo_1->swap_offset; - if (voodoo_1->swap_count > 0) - voodoo_1->swap_count--; - voodoo_1->swap_pending = 0; - - thread_set_event(voodoo->wake_fifo_thread); - thread_set_event(voodoo_1->wake_fifo_thread); - - voodoo->frame_count++; - voodoo_1->frame_count++; - } - } - } - else - { - if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) - { - memset(voodoo->dirty_line, 1, 1024); - voodoo->retrace_count = 0; - voodoo->front_offset = voodoo->swap_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; - thread_set_event(voodoo->wake_fifo_thread); - voodoo->frame_count++; - } - } - voodoo->v_retrace = 1; - } - voodoo->line++; - - if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) - { - if (voodoo->line == voodoo->v_disp) - { - if (voodoo->dirty_line_high > voodoo->dirty_line_low) - svga_doblit(0, voodoo->v_disp, voodoo->h_disp, voodoo->v_disp-1, voodoo->svga); - if (voodoo->clutData_dirty) - { - voodoo->clutData_dirty = 0; - voodoo_calc_clutData(voodoo); - } - voodoo->dirty_line_high = -1; - voodoo->dirty_line_low = 2000; - } - } - - if (voodoo->line >= voodoo->v_total) - { - voodoo->line = 0; - voodoo->v_retrace = 0; - } - if (voodoo->line_time) - voodoo->timer_count += voodoo->line_time; - else - voodoo->timer_count += TIMER_USEC * 32; -} - -static void voodoo_speed_changed(void *p) -{ - voodoo_set_t *voodoo_set = (voodoo_set_t *)p; - - voodoo_pixelclock_update(voodoo_set->voodoos[0]); - voodoo_set->voodoos[0]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit4 & 1) ? 2 : 1); - voodoo_set->voodoos[0]->write_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 1 : 0); - voodoo_set->voodoos[0]->burst_time = pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 2 : 1); - if (voodoo_set->nr_cards == 2) - { - voodoo_pixelclock_update(voodoo_set->voodoos[1]); - voodoo_set->voodoos[1]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit4 & 1) ? 2 : 1); - voodoo_set->voodoos[1]->write_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 1 : 0); - voodoo_set->voodoos[1]->burst_time = pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 2 : 1); - } -// voodoo_log("Voodoo read_time=%i write_time=%i burst_time=%i %08x %08x\n", voodoo->read_time, voodoo->write_time, voodoo->burst_time, voodoo->fbiInit1, voodoo->fbiInit4); -} - -void *voodoo_card_init() -{ - int c; - voodoo_t *voodoo = malloc(sizeof(voodoo_t)); - memset(voodoo, 0, sizeof(voodoo_t)); - - voodoo->bilinear_enabled = device_get_config_int("bilinear"); - voodoo->scrfilter = device_get_config_int("dacfilter"); - voodoo->texture_size = device_get_config_int("texture_memory"); - voodoo->texture_mask = (voodoo->texture_size << 20) - 1; - voodoo->fb_size = device_get_config_int("framebuffer_memory"); - voodoo->fb_mask = (voodoo->fb_size << 20) - 1; - voodoo->render_threads = device_get_config_int("render_threads"); - voodoo->odd_even_mask = voodoo->render_threads - 1; -#ifndef NO_CODEGEN - voodoo->use_recompiler = device_get_config_int("recompiler"); -#endif - voodoo->type = device_get_config_int("type"); - switch (voodoo->type) - { - case VOODOO_1: - voodoo->dual_tmus = 0; - break; - case VOODOO_SB50: - voodoo->dual_tmus = 1; - break; - case VOODOO_2: - voodoo->dual_tmus = 1; - break; - } - - if (voodoo->type == VOODOO_2) /*generate filter lookup tables*/ - voodoo_generate_filter_v2(voodoo); - else - voodoo_generate_filter_v1(voodoo); - - pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo); - - mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo); - - voodoo->fb_mem = malloc(4 * 1024 * 1024); - voodoo->tex_mem[0] = malloc(voodoo->texture_size * 1024 * 1024); - if (voodoo->dual_tmus) - voodoo->tex_mem[1] = malloc(voodoo->texture_size * 1024 * 1024); - voodoo->tex_mem_w[0] = (uint16_t *)voodoo->tex_mem[0]; - voodoo->tex_mem_w[1] = (uint16_t *)voodoo->tex_mem[1]; - - for (c = 0; c < TEX_CACHE_MAX; c++) - { - voodoo->texture_cache[0][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4); - voodoo->texture_cache[0][c].base = -1; /*invalid*/ - voodoo->texture_cache[0][c].refcount = 0; - if (voodoo->dual_tmus) - { - voodoo->texture_cache[1][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4); - voodoo->texture_cache[1][c].base = -1; /*invalid*/ - voodoo->texture_cache[1][c].refcount = 0; - } - } - - timer_add(voodoo_callback, &voodoo->timer_count, TIMER_ALWAYS_ENABLED, voodoo); - - voodoo->svga = svga_get_pri(); - voodoo->fbiInit0 = 0; - - voodoo->wake_fifo_thread = thread_create_event(); - voodoo->wake_render_thread[0] = thread_create_event(); - voodoo->wake_render_thread[1] = thread_create_event(); - voodoo->wake_main_thread = thread_create_event(); - voodoo->fifo_not_full_event = thread_create_event(); - voodoo->render_not_full_event[0] = thread_create_event(); - voodoo->render_not_full_event[1] = thread_create_event(); - voodoo->fifo_thread = thread_create(fifo_thread, voodoo); - voodoo->render_thread[0] = thread_create(render_thread_1, voodoo); - if (voodoo->render_threads == 2) - voodoo->render_thread[1] = thread_create(render_thread_2, voodoo); - - timer_add(voodoo_wake_timer, &voodoo->wake_timer, &voodoo->wake_timer, (void *)voodoo); - - for (c = 0; c < 0x100; c++) - { - rgb332[c].r = c & 0xe0; - rgb332[c].g = (c << 3) & 0xe0; - rgb332[c].b = (c << 6) & 0xc0; - rgb332[c].r = rgb332[c].r | (rgb332[c].r >> 3) | (rgb332[c].r >> 6); - rgb332[c].g = rgb332[c].g | (rgb332[c].g >> 3) | (rgb332[c].g >> 6); - rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 2); - rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 4); - rgb332[c].a = 0xff; - - ai44[c].a = (c & 0xf0) | ((c & 0xf0) >> 4); - ai44[c].r = (c & 0x0f) | ((c & 0x0f) << 4); - ai44[c].g = ai44[c].b = ai44[c].r; - } - - for (c = 0; c < 0x10000; c++) - { - rgb565[c].r = (c >> 8) & 0xf8; - rgb565[c].g = (c >> 3) & 0xfc; - rgb565[c].b = (c << 3) & 0xf8; - rgb565[c].r |= (rgb565[c].r >> 5); - rgb565[c].g |= (rgb565[c].g >> 6); - rgb565[c].b |= (rgb565[c].b >> 5); - rgb565[c].a = 0xff; - - argb1555[c].r = (c >> 7) & 0xf8; - argb1555[c].g = (c >> 2) & 0xf8; - argb1555[c].b = (c << 3) & 0xf8; - argb1555[c].r |= (argb1555[c].r >> 5); - argb1555[c].g |= (argb1555[c].g >> 5); - argb1555[c].b |= (argb1555[c].b >> 5); - argb1555[c].a = (c & 0x8000) ? 0xff : 0; - - argb4444[c].a = (c >> 8) & 0xf0; - argb4444[c].r = (c >> 4) & 0xf0; - argb4444[c].g = c & 0xf0; - argb4444[c].b = (c << 4) & 0xf0; - argb4444[c].a |= (argb4444[c].a >> 4); - argb4444[c].r |= (argb4444[c].r >> 4); - argb4444[c].g |= (argb4444[c].g >> 4); - argb4444[c].b |= (argb4444[c].b >> 4); - - ai88[c].a = (c >> 8); - ai88[c].r = c & 0xff; - ai88[c].g = c & 0xff; - ai88[c].b = c & 0xff; - } -#ifndef NO_CODEGEN - voodoo_codegen_init(voodoo); -#endif - - voodoo->disp_buffer = 0; - voodoo->draw_buffer = 1; - - return voodoo; -} - -void *voodoo_init() -{ - voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t)); - uint32_t tmuConfig = 1; - int type; - memset(voodoo_set, 0, sizeof(voodoo_set_t)); - - type = device_get_config_int("type"); - - voodoo_set->nr_cards = device_get_config_int("sli") ? 2 : 1; - voodoo_set->voodoos[0] = voodoo_card_init(); - voodoo_set->voodoos[0]->set = voodoo_set; - if (voodoo_set->nr_cards == 2) - { - voodoo_set->voodoos[1] = voodoo_card_init(); - - voodoo_set->voodoos[1]->set = voodoo_set; - - if (type == VOODOO_2) - { - voodoo_set->voodoos[0]->fbiInit5 |= FBIINIT5_MULTI_CVG; - voodoo_set->voodoos[1]->fbiInit5 |= FBIINIT5_MULTI_CVG; - } - else - { - voodoo_set->voodoos[0]->fbiInit1 |= FBIINIT1_MULTI_SST; - voodoo_set->voodoos[1]->fbiInit1 |= FBIINIT1_MULTI_SST; - } - } - - switch (type) - { - case VOODOO_1: - if (voodoo_set->nr_cards == 2) - tmuConfig = 1 | (3 << 3); - else - tmuConfig = 1; - break; - case VOODOO_SB50: - if (voodoo_set->nr_cards == 2) - tmuConfig = 1 | (3 << 3) | (3 << 6) | (2 << 9); - else - tmuConfig = 1 | (3 << 6); - break; - case VOODOO_2: - tmuConfig = 1 | (3 << 6); - break; - } - - voodoo_set->voodoos[0]->tmuConfig = tmuConfig; - if (voodoo_set->nr_cards == 2) - voodoo_set->voodoos[1]->tmuConfig = tmuConfig; - - mem_mapping_add(&voodoo_set->snoop_mapping, 0, 0, NULL, voodoo_snoop_readw, voodoo_snoop_readl, NULL, voodoo_snoop_writew, voodoo_snoop_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo_set); - - return voodoo_set; -} - -void voodoo_card_close(voodoo_t *voodoo) -{ -#ifndef RELEASE_BUILD - FILE *f; -#endif - int c; - -#ifndef RELEASE_BUILD - f = rom_fopen(L"texram.dmp", L"wb"); - fwrite(voodoo->tex_mem[0], voodoo->texture_size*1024*1024, 1, f); - fclose(f); - if (voodoo->dual_tmus) - { - f = rom_fopen(L"texram2.dmp", L"wb"); - fwrite(voodoo->tex_mem[1], voodoo->texture_size*1024*1024, 1, f); - fclose(f); - } -#endif - - thread_kill(voodoo->fifo_thread); - thread_kill(voodoo->render_thread[0]); - if (voodoo->render_threads == 2) - thread_kill(voodoo->render_thread[1]); - thread_destroy_event(voodoo->fifo_not_full_event); - thread_destroy_event(voodoo->wake_main_thread); - thread_destroy_event(voodoo->wake_fifo_thread); - thread_destroy_event(voodoo->wake_render_thread[0]); - thread_destroy_event(voodoo->wake_render_thread[1]); - thread_destroy_event(voodoo->render_not_full_event[0]); - thread_destroy_event(voodoo->render_not_full_event[1]); - - for (c = 0; c < TEX_CACHE_MAX; c++) - { - if (voodoo->dual_tmus) - free(voodoo->texture_cache[1][c].data); - free(voodoo->texture_cache[0][c].data); - } -#ifndef NO_CODEGEN - voodoo_codegen_close(voodoo); -#endif - free(voodoo->fb_mem); - if (voodoo->dual_tmus) - free(voodoo->tex_mem[1]); - free(voodoo->tex_mem[0]); - free(voodoo); -} - -void voodoo_close(void *p) -{ - voodoo_set_t *voodoo_set = (voodoo_set_t *)p; - - if (voodoo_set->nr_cards == 2) - voodoo_card_close(voodoo_set->voodoos[1]); - voodoo_card_close(voodoo_set->voodoos[0]); - - free(voodoo_set); -} - -static const device_config_t voodoo_config[] = -{ - { - .name = "type", - .description = "Voodoo type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Voodoo Graphics", - .value = VOODOO_1 - }, - { - .description = "Obsidian SB50 + Amethyst (2 TMUs)", - .value = VOODOO_SB50 - }, - { - .description = "Voodoo 2", - .value = VOODOO_2 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .name = "framebuffer_memory", - .description = "Framebuffer memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .name = "texture_memory", - .description = "Texture memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dacfilter", - .description = "Screen Filter", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "render_threads", - .description = "Render threads", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1", - .value = 1 - }, - { - .description = "2", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .name = "sli", - .description = "SLI", - .type = CONFIG_BINARY, - .default_int = 0 - }, -#ifndef NO_CODEGEN - { - .name = "recompiler", - .description = "Recompiler", - .type = CONFIG_BINARY, - .default_int = 1 - }, -#endif - { - .type = -1 - } -}; - -const device_t voodoo_device = -{ - "3DFX Voodoo Graphics", - DEVICE_PCI, - 0, - voodoo_init, - voodoo_close, - NULL, - NULL, - voodoo_speed_changed, - NULL, - voodoo_config -}; diff --git a/backup code/video - Cópia/vid_voodoo.h b/backup code/video - Cópia/vid_voodoo.h deleted file mode 100644 index 9752899f7..000000000 --- a/backup code/video - Cópia/vid_voodoo.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t voodoo_device; diff --git a/backup code/video - Cópia/vid_voodoo_codegen_x86-64.h b/backup code/video - Cópia/vid_voodoo_codegen_x86-64.h deleted file mode 100644 index bbb4be868..000000000 --- a/backup code/video - Cópia/vid_voodoo_codegen_x86-64.h +++ /dev/null @@ -1,3349 +0,0 @@ -/*Registers : - - alphaMode - fbzMode & 0x1f3fff - fbzColorPath -*/ - -#ifdef __linux__ -# include -# include -#endif -#if WIN64 -# include -#endif - -#include - -#define BLOCK_NUM 8 -#define BLOCK_MASK (BLOCK_NUM-1) -#define BLOCK_SIZE 8192 - -#define LOD_MASK (LOD_TMIRROR_S | LOD_TMIRROR_T) - -typedef struct voodoo_x86_data_t -{ - uint8_t code_block[BLOCK_SIZE]; - int xdir; - uint32_t alphaMode; - uint32_t fbzMode; - uint32_t fogMode; - uint32_t fbzColorPath; - uint32_t textureMode[2]; - uint32_t tLOD[2]; - uint32_t trexInit1; -} voodoo_x86_data_t; - -//static voodoo_x86_data_t voodoo_x86_data[2][BLOCK_NUM]; - -static int last_block[2] = {0, 0}; -static int next_block_to_write[2] = {0, 0}; - -#define addbyte(val) \ - code_block[block_pos++] = val; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") - -#define addword(val) \ - *(uint16_t *)&code_block[block_pos] = val; \ - block_pos += 2; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") - -#define addlong(val) \ - *(uint32_t *)&code_block[block_pos] = val; \ - block_pos += 4; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") - -#define addquad(val) \ - *(uint64_t *)&code_block[block_pos] = val; \ - block_pos += 8; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") - - -static __m128i xmm_01_w;// = 0x0001000100010001ull; -static __m128i xmm_ff_w;// = 0x00ff00ff00ff00ffull; -static __m128i xmm_ff_b;// = 0x00000000ffffffffull; - -static uint32_t zero = 0; - -static __m128i alookup[257], aminuslookup[256]; -static __m128i minus_254;// = 0xff02ff02ff02ff02ull; -static __m128i bilinear_lookup[256*2]; -static __m128i xmm_00_ff_w[2]; -static uint32_t i_00_ff_w[2] = {0, 0xff}; - -static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int block_pos, int tmu) -{ - if (params->textureMode[tmu] & 1) - { - addbyte(0x48); /*MOV RBX, state->tmu0_s*/ - addbyte(0x8b); - addbyte(0x9f); - addlong(tmu ? offsetof(voodoo_state_t, tmu1_s) : offsetof(voodoo_state_t, tmu0_s)); - addbyte(0x48); /*MOV RAX, (1 << 48)*/ - addbyte(0xb8); - addquad(1ULL << 48); - addbyte(0x48); /*XOR RDX, RDX*/ - addbyte(0x31); - addbyte(0xd2); - addbyte(0x48); /*MOV RCX, state->tmu0_t*/ - addbyte(0x8b); - addbyte(0x8f); - addlong(tmu ? offsetof(voodoo_state_t, tmu1_t) : offsetof(voodoo_state_t, tmu0_t)); - addbyte(0x48); /*CMP state->tmu_w, 0*/ - addbyte(0x83); - addbyte(0xbf); - addlong(tmu ? offsetof(voodoo_state_t, tmu1_w) : offsetof(voodoo_state_t, tmu0_w)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7); - addbyte(0x48); /*IDIV state->tmu_w*/ - addbyte(0xf7); - addbyte(0xbf); - addlong(tmu ? offsetof(voodoo_state_t, tmu1_w) : offsetof(voodoo_state_t, tmu0_w)); - addbyte(0x48); /*SAR RBX, 14*/ - addbyte(0xc1); - addbyte(0xfb); - addbyte(14); - addbyte(0x48); /*SAR RCX, 14*/ - addbyte(0xc1); - addbyte(0xf9); - addbyte(14); - addbyte(0x48); /*IMUL RBX, RAX*/ - addbyte(0x0f); - addbyte(0xaf); - addbyte(0xd8); - addbyte(0x48); /*IMUL RCX, RAX*/ - addbyte(0x0f); - addbyte(0xaf); - addbyte(0xc8); - addbyte(0x48); /*SAR RBX, 30*/ - addbyte(0xc1); - addbyte(0xfb); - addbyte(30); - addbyte(0x48); /*SAR RCX, 30*/ - addbyte(0xc1); - addbyte(0xf9); - addbyte(30); - addbyte(0x48); /*BSR EDX, RAX*/ - addbyte(0x0f); - addbyte(0xbd); - addbyte(0xd0); - addbyte(0x48); /*SHL RAX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - addbyte(0x89); /*MOV state->tex_t, ECX*/ - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, tex_t)); - addbyte(0x89); /*MOV ECX, EDX*/ - addbyte(0xd1); - addbyte(0x83); /*SUB EDX, 19*/ - addbyte(0xea); - addbyte(19); - addbyte(0x48); /*SHR RAX, CL*/ - addbyte(0xd3); - addbyte(0xe8); - addbyte(0xc1); /*SHL EDX, 8*/ - addbyte(0xe2); - addbyte(8); - addbyte(0x25); /*AND EAX, 0xff*/ - addlong(0xff); - addbyte(0x89); /*MOV state->tex_s, EBX*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tex_s)); - addbyte(0x0f); /*MOVZX EAX, logtable[RAX]*/ - addbyte(0xb6); - addbyte(0x80); - addlong((uint32_t)(uintptr_t)logtable); - addbyte(0x09); /*OR EAX, EDX*/ - addbyte(0xd0); - addbyte(0x03); /*ADD EAX, state->lod*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tmu[tmu].lod)); - addbyte(0x3b); /*CMP EAX, state->lod_min*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_min[tmu])); - addbyte(0x0f); /*CMOVL EAX, state->lod_min*/ - addbyte(0x4c); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_min[tmu])); - addbyte(0x3b); /*CMP EAX, state->lod_max*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_max[tmu])); - addbyte(0x0f); /*CMOVNL EAX, state->lod_max*/ - addbyte(0x4d); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_max[tmu])); - addbyte(0xc1); /*SHR EAX, 8*/ - addbyte(0xe8); - addbyte(8); - addbyte(0x89); /*MOV state->lod, EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod)); - } - else - { - addbyte(0x48); /*MOV RAX, state->tmu0_s*/ - addbyte(0x8b); - addbyte(0x87); - addlong(tmu ? offsetof(voodoo_state_t, tmu1_s) : offsetof(voodoo_state_t, tmu0_s)); - addbyte(0x48); /*MOV RCX, state->tmu0_t*/ - addbyte(0x8b); - addbyte(0x8f); - addlong(tmu ? offsetof(voodoo_state_t, tmu1_t) : offsetof(voodoo_state_t, tmu0_t)); - addbyte(0x48); /*SHR RAX, 28*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(28); - addbyte(0x8b); /*MOV EBX, state->lod_min*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, lod_min[tmu])); - addbyte(0x48); /*SHR RCX, 28*/ - addbyte(0xc1); - addbyte(0xe9); - addbyte(28); - addbyte(0x48); /*MOV state->tex_s, RAX*/ - addbyte(0x89); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_s)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x48); /*MOV state->tex_t, RCX*/ - addbyte(0x89); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, tex_t)); - addbyte(0x89); /*MOV state->lod, EBX*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, lod)); - } - - if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) - { - if (voodoo->bilinear_enabled && (params->textureMode[tmu] & 6)) - { - addbyte(0xb2); /*MOV DL, 8*/ - addbyte(8); - addbyte(0x8b); /*MOV ECX, state->lod[RDI]*/ - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, lod)); - addbyte(0xbd); /*MOV EBP, 1*/ - addlong(1); - addbyte(0x28); /*SUB DL, CL*/ - addbyte(0xca); -// addbyte(0x8a); /*MOV DL, params->tex_shift[RSI+ECX*4]*/ -// addbyte(0x94); -// addbyte(0x8e); -// addlong(offsetof(voodoo_params_t, tex_shift)); - addbyte(0xd3); /*SHL EBP, CL*/ - addbyte(0xe5); - addbyte(0x8b); /*MOV EAX, state->tex_s[RDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_s)); - addbyte(0xc1); /*SHL EBP, 3*/ - addbyte(0xe5); - addbyte(3); - addbyte(0x8b); /*MOV EBX, state->tex_t[RDI]*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tex_t)); - if (params->tLOD[tmu] & LOD_TMIRROR_S) - { - addbyte(0xa9); /*TEST EAX, 0x1000*/ - addlong(0x1000); - addbyte(0x74); /*JZ +*/ - addbyte(2); - addbyte(0xf7); /*NOT EAX*/ - addbyte(0xd0); - } - if (params->tLOD[tmu] & LOD_TMIRROR_T) - { - addbyte(0xf7); /*TEST EBX, 0x1000*/ - addbyte(0xc3); - addlong(0x1000); - addbyte(0x74); /*JZ +*/ - addbyte(2); - addbyte(0xf7); /*NOT EBX*/ - addbyte(0xd3); - } - addbyte(0x29); /*SUB EAX, EBP*/ - addbyte(0xe8); - addbyte(0x29); /*SUB EBX, EBP*/ - addbyte(0xeb); - addbyte(0xd3); /*SAR EAX, CL*/ - addbyte(0xf8); - addbyte(0xd3); /*SAR EBX, CL*/ - addbyte(0xfb); - addbyte(0x89); /*MOV EBP, EAX*/ - addbyte(0xc5); - addbyte(0x89); /*MOV ECX, EBX*/ - addbyte(0xd9); - addbyte(0x83); /*AND EBP, 0xf*/ - addbyte(0xe5); - addbyte(0xf); - addbyte(0xc1); /*SHL ECX, 4*/ - addbyte(0xe1); - addbyte(4); - addbyte(0xc1); /*SAR EAX, 4*/ - addbyte(0xf8); - addbyte(4); - addbyte(0x81); /*AND ECX, 0xf0*/ - addbyte(0xe1); - addlong(0xf0); - addbyte(0xc1); /*SAR EBX, 4*/ - addbyte(0xfb); - addbyte(4); - addbyte(0x09); /*OR EBP, ECX*/ - addbyte(0xcd); - addbyte(0x8b); /*MOV ECX, state->lod[RDI]*/ - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, lod)); - addbyte(0xc1); /*SHL EBP, 5*/ - addbyte(0xe5); - addbyte(5); - /*EAX = S, EBX = T, ECX = LOD, EDX = tex_shift, ESI=params, EDI=state, EBP = bilinear shift*/ - addbyte(0x48); /*LEA RSI, [RSI+RCX*4]*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x8e); - addbyte(0x89); /*MOV ebp_store, EBP*/ - addbyte(0xaf); - addlong(offsetof(voodoo_state_t, ebp_store)); - addbyte(0x48); /*MOV RBP, state->tex[RDI+RCX*8]*/ - addbyte(0x8b); - addbyte(0xac); - addbyte(0xcf); - addlong(offsetof(voodoo_state_t, tex[tmu])); - addbyte(0x88); /*MOV CL, DL*/ - addbyte(0xd1); - addbyte(0x89); /*MOV EDX, EBX*/ - addbyte(0xda); - if (!state->clamp_s[tmu]) - { - addbyte(0x23); /*AND EAX, params->tex_w_mask[ESI]*/ - addbyte(0x86); - addlong(offsetof(voodoo_params_t, tex_w_mask[tmu])); - } - addbyte(0x83); /*ADD EDX, 1*/ - addbyte(0xc2); - addbyte(1); - if (state->clamp_t[tmu]) - { - addbyte(0x0f); /*CMOVS EDX, zero*/ - addbyte(0x48); - addbyte(0x14); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&zero); - addbyte(0x3b); /*CMP EDX, params->tex_h_mask[ESI]*/ - addbyte(0x96); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - addbyte(0x0f); /*CMOVA EDX, params->tex_h_mask[ESI]*/ - addbyte(0x47); - addbyte(0x96); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - addbyte(0x85); /*TEST EBX,EBX*/ - addbyte(0xdb); - addbyte(0x0f); /*CMOVS EBX, zero*/ - addbyte(0x48); - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&zero); - addbyte(0x3b); /*CMP EBX, params->tex_h_mask[ESI]*/ - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - addbyte(0x0f); /*CMOVA EBX, params->tex_h_mask[ESI]*/ - addbyte(0x47); - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - } - else - { - addbyte(0x23); /*AND EDX, params->tex_h_mask[ESI]*/ - addbyte(0x96); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - addbyte(0x23); /*AND EBX, params->tex_h_mask[ESI]*/ - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - } - /*EAX = S, EBX = T0, EDX = T1*/ - addbyte(0xd3); /*SHL EBX, CL*/ - addbyte(0xe3); - addbyte(0xd3); /*SHL EDX, CL*/ - addbyte(0xe2); - addbyte(0x48); /*LEA RBX,[RBP+RBX*4]*/ - addbyte(0x8d); - addbyte(0x5c); - addbyte(0x9d); - addbyte(0); - addbyte(0x48); /*LEA RDX,[RBP+RDX*4]*/ - addbyte(0x8d); - addbyte(0x54); - addbyte(0x95); - addbyte(0); - if (state->clamp_s[tmu]) - { - addbyte(0x8b); /*MOV EBP, params->tex_w_mask[ESI]*/ - addbyte(0xae); - addlong(offsetof(voodoo_params_t, tex_w_mask[tmu])); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x8b); /*MOV ebp_store2, RSI*/ - addbyte(0xb7); - addlong(offsetof(voodoo_state_t, ebp_store)); - addbyte(0x0f); /*CMOVS EAX, zero*/ - addbyte(0x48); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&zero); - addbyte(0x78); /*JS + - clamp on 0*/ - addbyte(2+3+2+ 5+5+2); - addbyte(0x3b); /*CMP EAX, EBP*/ - addbyte(0xc5); - addbyte(0x0f); /*CMOVAE EAX, EBP*/ - addbyte(0x43); - addbyte(0xc5); - addbyte(0x73); /*JAE + - clamp on +*/ - addbyte(5+5+2); - } - else - { - addbyte(0x3b); /*CMP EAX, params->tex_w_mask[ESI] - is S at texture edge (ie will wrap/clamp)?*/ - addbyte(0x86); - addlong(offsetof(voodoo_params_t, tex_w_mask[tmu])); - addbyte(0x8b); /*MOV ebp_store2, ESI*/ - addbyte(0xb7); - addlong(offsetof(voodoo_state_t, ebp_store)); - addbyte(0x74); /*JE +*/ - addbyte(5+5+2); - } - - addbyte(0xf3); /*MOVQ XMM0, [RBX+RAX*4]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x04); - addbyte(0x83); - addbyte(0xf3); /*MOVQ XMM1, [RDX+RAX*4]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x0c); - addbyte(0x82); - - if (state->clamp_s[tmu]) - { - addbyte(0xeb); /*JMP +*/ - addbyte(5+5+4+4); - - /*S clamped - the two S coordinates are the same*/ - addbyte(0x66); /*MOVD XMM0, [RBX+RAX*4]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x04); - addbyte(0x83); - addbyte(0x66); /*MOVD XMM1, [RDX+RAX*4]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x0c); - addbyte(0x82); - addbyte(0x66); /*PUNPCKLDQ XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0); - addbyte(0x66); /*PUNPCKLDQ XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc9); - } - else - { - addbyte(0xeb); /*JMP +*/ - addbyte(5+5+5+5+6+6); - - /*S wrapped - the two S coordinates are not contiguous*/ - addbyte(0x66); /*MOVD XMM0, [RBX+EAX*4]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x04); - addbyte(0x83); - addbyte(0x66); /*MOVD XMM1, [RDX+EAX*4]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x0c); - addbyte(0x82); - addbyte(0x66); /*PINSRW XMM0, [RBX], 2*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x03); - addbyte(0x02); - addbyte(0x66); /*PINSRW XMM1, [RDX], 2*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x0a); - addbyte(0x02); - addbyte(0x66); /*PINSRW XMM0, 2[RBX], 3*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x43); - addbyte(0x02); - addbyte(0x03); - addbyte(0x66); /*PINSRW XMM1, 2[RDX], 3*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x4a); - addbyte(0x02); - addbyte(0x03); - } - - addbyte(0x49); /*MOV R8, bilinear_lookup*/ - addbyte(0xb8); - addquad((uintptr_t)bilinear_lookup); - - addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc2); - addbyte(0x66); /*PUNPCKLBW XMM1, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xca); - - addbyte(0x4c); /*ADD RSI, R8*/ - addbyte(0x01); - addbyte(0xc6); - - addbyte(0x66); /*PMULLW XMM0, bilinear_lookup[ESI]*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x06); - addbyte(0x66); /*PMULLW XMM1, bilinear_lookup[ESI]+0x10*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x4e); - addbyte(0x10); - addbyte(0x66); /*PADDW XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc0 | 1 | (0 << 3)); - addbyte(0x66); /*MOV XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0xc0 | 0 | (1 << 3)); - addbyte(0x66); /*PSRLDQ XMM0, 64*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xd8); - addbyte(8); - addbyte(0x66); /*PADDW XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc0 | 1 | (0 << 3)); - addbyte(0x66); /*PSRLW XMM0, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd0 | 0); - addbyte(8); - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); - - addbyte(0x4c); /*MOV RSI, R15*/ - addbyte(0x89); - addbyte(0xfe); - - addbyte(0x66); /*MOV EAX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc0); - } - else - { - addbyte(0xb2); /*MOV DL, 8*/ - addbyte(8); - addbyte(0x8b); /*MOV ECX, state->lod[RDI]*/ - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, lod)); - addbyte(0x48); /*MOV RBP, state->tex[RDI+RCX*8]*/ - addbyte(0x8b); - addbyte(0xac); - addbyte(0xcf); - addlong(offsetof(voodoo_state_t, tex[tmu])); - addbyte(0x28); /*SUB DL, CL*/ - addbyte(0xca); - addbyte(0x80); /*ADD CL, 4*/ - addbyte(0xc1); - addbyte(4); - addbyte(0x8b); /*MOV EAX, state->tex_s[EDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_s)); - addbyte(0x8b); /*MOV EBX, state->tex_t[EDI]*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tex_t)); - if (params->tLOD[tmu] & LOD_TMIRROR_S) - { - addbyte(0xa9); /*TEST EAX, 0x1000*/ - addlong(0x1000); - addbyte(0x74); /*JZ +*/ - addbyte(2); - addbyte(0xf7); /*NOT EAX*/ - addbyte(0xd0); - } - if (params->tLOD[tmu] & LOD_TMIRROR_T) - { - addbyte(0xf7); /*TEST EBX, 0x1000*/ - addbyte(0xc3); - addlong(0x1000); - addbyte(0x74); /*JZ +*/ - addbyte(2); - addbyte(0xf7); /*NOT EBX*/ - addbyte(0xd3); - } - addbyte(0xd3); /*SHR EAX, CL*/ - addbyte(0xe8); - addbyte(0xd3); /*SHR EBX, CL*/ - addbyte(0xeb); - if (state->clamp_s[tmu]) - { - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*CMOVS EAX, zero*/ - addbyte(0x48); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&zero); - addbyte(0x3b); /*CMP EAX, params->tex_w_mask[ESI+ECX*4]*/ - addbyte(0x84); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, tex_w_mask[tmu]) - 0x10); - addbyte(0x0f); /*CMOVAE EAX, params->tex_w_mask[ESI+ECX*4]*/ - addbyte(0x43); - addbyte(0x84); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, tex_w_mask[tmu]) - 0x10); - - } - else - { - addbyte(0x23); /*AND EAX, params->tex_w_mask-0x10[ESI+ECX*4]*/ - addbyte(0x84); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, tex_w_mask[tmu]) - 0x10); - } - if (state->clamp_t[tmu]) - { - addbyte(0x85); /*TEST EBX, EBX*/ - addbyte(0xdb); - addbyte(0x0f); /*CMOVS EBX, zero*/ - addbyte(0x48); - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&zero); - addbyte(0x3b); /*CMP EBX, params->tex_h_mask[ESI+ECX*4]*/ - addbyte(0x9c); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu]) - 0x10); - addbyte(0x0f); /*CMOVAE EBX, params->tex_h_mask[ESI+ECX*4]*/ - addbyte(0x43); - addbyte(0x9c); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu]) - 0x10); - } - else - { - addbyte(0x23); /*AND EBX, params->tex_h_mask-0x10[ESI+ECX*4]*/ - addbyte(0x9c); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu]) - 0x10); - } - addbyte(0x88); /*MOV CL, DL*/ - addbyte(0xd1); - addbyte(0xd3); /*SHL EBX, CL*/ - addbyte(0xe3); - addbyte(0x01); /*ADD EBX, EAX*/ - addbyte(0xc3); - - addbyte(0x8b); /*MOV EAX, [RBP+RBX*4]*/ - addbyte(0x44); - addbyte(0x9d); - addbyte(0); - } - } - - return block_pos; -} - -static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int depthop) -{ - int block_pos = 0; - int z_skip_pos = 0; - int a_skip_pos = 0; - int chroma_skip_pos = 0; - int depth_jump_pos = 0; - int depth_jump_pos2 = 0; - int loop_jump_pos = 0; -// xmm_01_w = (__m128i)0x0001000100010001ull; -// xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull; -// xmm_ff_b = (__m128i)0x00000000ffffffffull; - xmm_01_w = _mm_set_epi32(0, 0, 0x00010001, 0x00010001); - xmm_ff_w = _mm_set_epi32(0, 0, 0x00ff00ff, 0x00ff00ff); - xmm_ff_b = _mm_set_epi32(0, 0, 0, 0x00ffffff); - minus_254 = _mm_set_epi32(0, 0, 0xff02ff02, 0xff02ff02); -// *(uint64_t *)&const_1_48 = 0x45b0000000000000ull; -// block_pos = 0; -// voodoo_get_depth = &code_block[block_pos]; - /*W at (%esp+4) - Z at (%esp+12) - new_depth at (%esp+16)*/ -// if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depth_op == DEPTHOP_NEVER)) -// { -// addbyte(0xC3); /*RET*/ -// return; -// } - addbyte(0x55); /*PUSH RBP*/ - addbyte(0x57); /*PUSH RDI*/ - addbyte(0x56); /*PUSH RSI*/ - addbyte(0x53); /*PUSH RBX*/ - addbyte(0x41); /*PUSH R14*/ - addbyte(0x56); - addbyte(0x41); /*PUSH R15*/ - addbyte(0x57); - -#if WIN64 - addbyte(0x48); /*MOV RDI, RCX (voodoo_state)*/ - addbyte(0x89); - addbyte(0xcf); - addbyte(0x49); /*MOV R15, RDX (voodoo_params)*/ - addbyte(0x89); - addbyte(0xd7); - addbyte(0x4d); /*MOV R14, R9 (real_y)*/ - addbyte(0x89); - addbyte(0xce); -#else - addbyte(0x49); /*MOV R9, RCX (real_y)*/ - addbyte(0x89); - addbyte(0xc9); - addbyte(0x49); /*MOV R15, RSI (voodoo_state)*/ - addbyte(0x89); - addbyte(0xf7); -#endif - loop_jump_pos = block_pos; - addbyte(0x4c); /*MOV RSI, R15*/ - addbyte(0x89); - addbyte(0xfe); - addbyte(0x66); /*PXOR XMM2, XMM2*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xd2); - - if ((params->fbzMode & FBZ_W_BUFFER) || (params->fogMode & (FOG_ENABLE|FOG_CONSTANT|FOG_Z|FOG_ALPHA)) == FOG_ENABLE) - { - addbyte(0xb8); /*MOV new_depth, 0*/ - addlong(0); - addbyte(0x66); /*TEST w+4, 0xffff*/ - addbyte(0xf7); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, w)+4); - addword(0xffff); - addbyte(0x75); /*JNZ got_depth*/ - depth_jump_pos = block_pos; - addbyte(0); -// addbyte(4+5+2+3+2+5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); - addbyte(0x8b); /*MOV EDX, w*/ - addbyte(0x97); - addlong(offsetof(voodoo_state_t, w)); - addbyte(0xb8); /*MOV new_depth, 0xf001*/ - addlong(0xf001); - addbyte(0x89); /*MOV EBX, EDX*/ - addbyte(0xd3); - addbyte(0xc1); /*SHR EDX, 16*/ - addbyte(0xea); - addbyte(16); - addbyte(0x74); /*JZ got_depth*/ - depth_jump_pos2 = block_pos; - addbyte(0); -// addbyte(5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); - addbyte(0xb9); /*MOV ECX, 19*/ - addlong(19); - addbyte(0x0f); /*BSR EAX, EDX*/ - addbyte(0xbd); - addbyte(0xc2); - addbyte(0xba); /*MOV EDX, 15*/ - addlong(15); - addbyte(0xf7); /*NOT EBX*/ - addbyte(0xd3); - addbyte(0x29); /*SUB EDX, EAX - EDX = exp*/ - addbyte(0xc2); - addbyte(0x29); /*SUB ECX, EDX*/ - addbyte(0xd1); - addbyte(0xc1); /*SHL EDX, 12*/ - addbyte(0xe2); - addbyte(12); - addbyte(0xd3); /*SHR EBX, CL*/ - addbyte(0xeb); - addbyte(0x81); /*AND EBX, 0xfff - EBX = mant*/ - addbyte(0xe3); - addlong(0xfff); - addbyte(0x67); /*LEA EAX, 1[EDX, EBX]*/ - addbyte(0x8d); - addbyte(0x44); - addbyte(0x13); - addbyte(1); - addbyte(0xbb); /*MOV EBX, 0xffff*/ - addlong(0xffff); - addbyte(0x39); /*CMP EAX, EBX*/ - addbyte(0xd8); - addbyte(0x0f); /*CMOVA EAX, EBX*/ - addbyte(0x47); - addbyte(0xc3); - - if (depth_jump_pos) - *(uint8_t *)&code_block[depth_jump_pos] = (block_pos - depth_jump_pos) - 1; - if (depth_jump_pos) - *(uint8_t *)&code_block[depth_jump_pos2] = (block_pos - depth_jump_pos2) - 1; - - if ((params->fogMode & (FOG_ENABLE|FOG_CONSTANT|FOG_Z|FOG_ALPHA)) == FOG_ENABLE) - { - addbyte(0x89); /*MOV state->w_depth[EDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, w_depth)); - } - } - if (!(params->fbzMode & FBZ_W_BUFFER)) - { - addbyte(0x8b); /*MOV EAX, z*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, z)); - addbyte(0xbb); /*MOV EBX, 0xffff*/ - addlong(0xffff); - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - addbyte(0xc1); /*SAR EAX, 12*/ - addbyte(0xf8); - addbyte(12); - addbyte(0x0f); /*CMOVS EAX, ECX*/ - addbyte(0x48); - addbyte(0xc1); - addbyte(0x39); /*CMP EAX, EBX*/ - addbyte(0xd8); - addbyte(0x0f); /*CMOVA EAX, EBX*/ - addbyte(0x47); - addbyte(0xc3); - } - - if (params->fbzMode & FBZ_DEPTH_BIAS) - { - addbyte(0x03); /*ADD EAX, params->zaColor[ESI]*/ - addbyte(0x86); - addlong(offsetof(voodoo_params_t, zaColor)); - addbyte(0x25); /*AND EAX, 0xffff*/ - addlong(0xffff); - } - - addbyte(0x89); /*MOV state->new_depth[EDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, new_depth)); - - if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop != DEPTHOP_ALWAYS) && (depthop != DEPTHOP_NEVER)) - { - addbyte(0x8b); /*MOV EBX, state->x[EDI]*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, x)); - addbyte(0x48); /*MOV RCX, aux_mem[RDI]*/ - addbyte(0x8b); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, aux_mem)); - addbyte(0x0f); /*MOVZX EBX, [ECX+EBX*2]*/ - addbyte(0xb7); - addbyte(0x1c); - addbyte(0x59); - if (params->fbzMode & FBZ_DEPTH_SOURCE) - { - addbyte(0x0f); /*MOVZX EAX, zaColor[RSI]*/ - addbyte(0xb7); - addbyte(0x86); - addlong(offsetof(voodoo_params_t, zaColor)); - } - addbyte(0x39); /*CMP EAX, EBX*/ - addbyte(0xd8); - if (depthop == DEPTHOP_LESSTHAN) - { - addbyte(0x0f); /*JAE skip*/ - addbyte(0x83); - z_skip_pos = block_pos; - addlong(0); - } - else if (depthop == DEPTHOP_EQUAL) - { - addbyte(0x0f); /*JNE skip*/ - addbyte(0x85); - z_skip_pos = block_pos; - addlong(0); - } - else if (depthop == DEPTHOP_LESSTHANEQUAL) - { - addbyte(0x0f); /*JA skip*/ - addbyte(0x87); - z_skip_pos = block_pos; - addlong(0); - } - else if (depthop == DEPTHOP_GREATERTHAN) - { - addbyte(0x0f); /*JBE skip*/ - addbyte(0x86); - z_skip_pos = block_pos; - addlong(0); - } - else if (depthop == DEPTHOP_NOTEQUAL) - { - addbyte(0x0f); /*JE skip*/ - addbyte(0x84); - z_skip_pos = block_pos; - addlong(0); - } - else if (depthop == DEPTHOP_GREATERTHANEQUAL) - { - addbyte(0x0f); /*JB skip*/ - addbyte(0x82); - z_skip_pos = block_pos; - addlong(0); - } - else - fatal("Bad depth_op\n"); - } - else if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop == DEPTHOP_NEVER)) - { - addbyte(0xC3); /*RET*/ - } - - /*XMM0 = colour*/ - /*XMM2 = 0 (for unpacking*/ - - /*EDI = state, ESI = params*/ - - if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || !voodoo->dual_tmus) - { - /*TMU0 only sampling local colour or only one TMU, only sample TMU0*/ - block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 0); - - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - addbyte(0xc1); /*SHR EAX, 24*/ - addbyte(0xe8); - addbyte(24); - addbyte(0x89); /*MOV state->tex_a[RDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_a)); - } - else if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH) - { - /*TMU0 in pass-through mode, only sample TMU1*/ - block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 1); - - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - addbyte(0xc1); /*SHR EAX, 24*/ - addbyte(0xe8); - addbyte(24); - addbyte(0x89); /*MOV state->tex_a[RDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_a)); - } - else - { - block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 1); - - addbyte(0x66); /*MOVD XMM3, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xd8); - if ((params->textureMode[1] & TEXTUREMODE_TRILINEAR) && tc_sub_clocal_1) - { - addbyte(0x8b); /*MOV EAX, state->lod*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod)); - if (!tc_reverse_blend_1) - { - addbyte(0xbb); /*MOV EBX, 1*/ - addlong(1); - } - else - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - addbyte(0x83); /*AND EAX, 1*/ - addbyte(0xe0); - addbyte(1); - if (!tca_reverse_blend_1) - { - addbyte(0xb9); /*MOV ECX, 1*/ - addlong(1); - } - else - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - addbyte(0x31); /*XOR EBX, EAX*/ - addbyte(0xc3); - addbyte(0x31); /*XOR ECX, EAX*/ - addbyte(0xc1); - addbyte(0xc1); /*SHL EBX, 4*/ - addbyte(0xe3); - addbyte(4); - /*EBX = tc_reverse_blend, ECX=tca_reverse_blend*/ - } - addbyte(0x66); /*PUNPCKLBW XMM3, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xda); - if (tc_sub_clocal_1) - { - switch (tc_mselect_1) - { - case TC_MSELECT_ZERO: - addbyte(0x66); /*PXOR XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xc0); - break; - case TC_MSELECT_CLOCAL: - addbyte(0xf3); /*MOVQ XMM0, XMM3*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc3); - break; - case TC_MSELECT_AOTHER: - addbyte(0x66); /*PXOR XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xc0); - break; - case TC_MSELECT_ALOCAL: - addbyte(0xf2); /*PSHUFLW XMM0, XMM3, 0xff*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc3); - addbyte(0xff); - break; - case TC_MSELECT_DETAIL: - addbyte(0xb8); /*MOV EAX, params->detail_bias[1]*/ - addlong(params->detail_bias[1]); - addbyte(0x2b); /*SUB EAX, state->lod*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod)); - addbyte(0xba); /*MOV EDX, params->detail_max[1]*/ - addlong(params->detail_max[1]); - addbyte(0xc1); /*SHL EAX, params->detail_scale[1]*/ - addbyte(0xe0); - addbyte(params->detail_scale[1]); - addbyte(0x39); /*CMP EAX, EDX*/ - addbyte(0xd0); - addbyte(0x0f); /*CMOVNL EAX, EDX*/ - addbyte(0x4d); - addbyte(0xc2); - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - addbyte(0xf2); /*PSHUFLW XMM0, XMM0, 0*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0); - addbyte(0); - break; - case TC_MSELECT_LOD_FRAC: - addbyte(0x66); /*MOVD XMM0, state->lod_frac[1]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_frac[1])); - addbyte(0xf2); /*PSHUFLW XMM0, XMM0, 0*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0); - addbyte(0); - break; - } - if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) - { - addbyte(0x66); /*PXOR XMM0, xmm_00_ff_w[EBX]*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x83); - addlong((uint32_t)(uintptr_t)&xmm_00_ff_w[0]); - } - else if (!tc_reverse_blend_1) - { - addbyte(0x66); /*PXOR XMM0, xmm_ff_w*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_ff_w); - } - addbyte(0x66); /*PADDW XMM0, xmm_01_w*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_01_w); - addbyte(0xf3); /*MOVQ XMM1, XMM2*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xca); - addbyte(0xf3); /*MOVQ XMM5, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe8); - addbyte(0x66); /*PMULLW XMM0, XMM3*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xc3); - addbyte(0x66); /*PMULHW XMM5, XMM3*/ - addbyte(0x0f); - addbyte(0xe5); - addbyte(0xeb); - addbyte(0x66); /*PUNPCKLWD XMM0, XMM5*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xc5); - addbyte(0x66); /*PSRAD XMM0, 8*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe0); - addbyte(8); - addbyte(0x66); /*PACKSSDW XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0); - addbyte(0x66); /*PSUBW XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xc8); - if (tc_add_clocal_1) - { - addbyte(0x66); /*PADDW XMM1, XMM3*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xcb); - } - else if (tc_add_alocal_1) - { - addbyte(0xf2); /*PSHUFLW XMM0, XMM3, 0xff*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc3); - addbyte(0xff); - addbyte(0x66); /*PADDW XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc8); - } - addbyte(0x66); /*PACKUSWB XMM3, XMM1*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xd9); - if (tca_sub_clocal_1) - { - addbyte(0x66); /*MOVD EBX, XMM3*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xdb); - } - addbyte(0x66); /*PUNPCKLBW XMM3, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xda); - } - - if (tca_sub_clocal_1) - { - addbyte(0xc1); /*SHR EBX, 24*/ - addbyte(0xeb); - addbyte(24); - switch (tca_mselect_1) - { - case TCA_MSELECT_ZERO: - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - break; - case TCA_MSELECT_CLOCAL: - addbyte(0x89); /*MOV EAX, EBX*/ - addbyte(0xd8); - break; - case TCA_MSELECT_AOTHER: - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - break; - case TCA_MSELECT_ALOCAL: - addbyte(0x89); /*MOV EAX, EBX*/ - addbyte(0xd8); - break; - case TCA_MSELECT_DETAIL: - addbyte(0xb8); /*MOV EAX, params->detail_bias[1]*/ - addlong(params->detail_bias[1]); - addbyte(0x2b); /*SUB EAX, state->lod*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod)); - addbyte(0xba); /*MOV EDX, params->detail_max[1]*/ - addlong(params->detail_max[1]); - addbyte(0xc1); /*SHL EAX, params->detail_scale[1]*/ - addbyte(0xe0); - addbyte(params->detail_scale[1]); - addbyte(0x39); /*CMP EAX, EDX*/ - addbyte(0xd0); - addbyte(0x0f); /*CMOVNL EAX, EDX*/ - addbyte(0x4d); - addbyte(0xc2); - break; - case TCA_MSELECT_LOD_FRAC: - addbyte(0x8b); /*MOV EAX, state->lod_frac[1]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_frac[1])); - break; - } - if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) - { - addbyte(0x33); /*XOR EAX, i_00_ff_w[ECX*4]*/ - addbyte(0x04); - addbyte(0x8d); - addlong((uint32_t)(uintptr_t)i_00_ff_w); - } - else if (!tc_reverse_blend_1) - { - addbyte(0x35); /*XOR EAX, 0xff*/ - addlong(0xff); - } - addbyte(0x8e); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(1); - addbyte(0x0f); /*IMUL EAX, EBX*/ - addbyte(0xaf); - addbyte(0xc3); - addbyte(0xb9); /*MOV ECX, 0xff*/ - addlong(0xff); - addbyte(0xf7); /*NEG EAX*/ - addbyte(0xd8); - addbyte(0xc1); /*SAR EAX, 8*/ - addbyte(0xf8); - addbyte(8); - if (tca_add_clocal_1 || tca_add_alocal_1) - { - addbyte(0x01); /*ADD EAX, EBX*/ - addbyte(0xd8); - } - addbyte(0x39); /*CMP ECX, EAX*/ - addbyte(0xc1); - addbyte(0x0f); /*CMOVA ECX, EAX*/ - addbyte(0x47); - addbyte(0xc8); - addbyte(0x66); /*PINSRW 3, XMM3, XMM0*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0xd8); - addbyte(3); - } - - block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 0); - - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - addbyte(0x66); /*MOVD XMM7, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xf8); - - if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) - { - addbyte(0x8b); /*MOV EAX, state->lod*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod)); - if (!tc_reverse_blend) - { - addbyte(0xbb); /*MOV EBX, 1*/ - addlong(1); - } - else - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - addbyte(0x83); /*AND EAX, 1*/ - addbyte(0xe0); - addbyte(1); - if (!tca_reverse_blend) - { - addbyte(0xb9); /*MOV ECX, 1*/ - addlong(1); - } - else - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - addbyte(0x31); /*XOR EBX, EAX*/ - addbyte(0xc3); - addbyte(0x31); /*XOR ECX, EAX*/ - addbyte(0xc1); - addbyte(0xc1); /*SHL EBX, 4*/ - addbyte(0xe3); - addbyte(4); - /*EBX = tc_reverse_blend, ECX=tca_reverse_blend*/ - } - - /*XMM0 = TMU0 output, XMM3 = TMU1 output*/ - - addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc2); - if (tc_zero_other) - { - addbyte(0x66); /*PXOR XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xc9); - } - else - { - addbyte(0xf3); /*MOV XMM1, XMM3*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xcb); - } - if (tc_sub_clocal) - { - addbyte(0x66); /*PSUBW XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xc8); - } - - switch (tc_mselect) - { - case TC_MSELECT_ZERO: - addbyte(0x66); /*PXOR XMM4, XMM4*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xe4); - break; - case TC_MSELECT_CLOCAL: - addbyte(0xf3); /*MOV XMM4, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe0); - break; - case TC_MSELECT_AOTHER: - addbyte(0xf2); /*PSHUFLW XMM4, XMM3, 3, 3, 3, 3*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xe3); - addbyte(0xff); - break; - case TC_MSELECT_ALOCAL: - addbyte(0xf2); /*PSHUFLW XMM4, XMM0, 3, 3, 3, 3*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xe0); - addbyte(0xff); - break; - case TC_MSELECT_DETAIL: - addbyte(0xb8); /*MOV EAX, params->detail_bias[0]*/ - addlong(params->detail_bias[0]); - addbyte(0x2b); /*SUB EAX, state->lod*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod)); - addbyte(0xba); /*MOV EDX, params->detail_max[0]*/ - addlong(params->detail_max[0]); - addbyte(0xc1); /*SHL EAX, params->detail_scale[0]*/ - addbyte(0xe0); - addbyte(params->detail_scale[0]); - addbyte(0x39); /*CMP EAX, EDX*/ - addbyte(0xd0); - addbyte(0x0f); /*CMOVNL EAX, EDX*/ - addbyte(0x4d); - addbyte(0xc2); - addbyte(0x66); /*MOVD XMM4, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xe0); - addbyte(0xf2); /*PSHUFLW XMM4, XMM4, 0*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xe4); - addbyte(0); - break; - case TC_MSELECT_LOD_FRAC: - addbyte(0x66); /*MOVD XMM0, state->lod_frac[0]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xa7); - addlong(offsetof(voodoo_state_t, lod_frac[0])); - addbyte(0xf2); /*PSHUFLW XMM0, XMM0, 0*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xe4); - addbyte(0); - break; - } - if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) - { - addbyte(0x66); /*PXOR XMM4, xmm_00_ff_w[EBX]*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xa3); - addlong((uint32_t)(uintptr_t)&xmm_00_ff_w[0]); - } - else if (!tc_reverse_blend) - { - addbyte(0x66); /*PXOR XMM4, FF*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_ff_w); - } - addbyte(0x66); /*PADDW XMM4, 1*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_01_w); - addbyte(0xf3); /*MOVQ XMM5, XMM1*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe9); - addbyte(0x66); /*PMULLW XMM1, XMM4*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xcc); - - if (tca_sub_clocal) - { - addbyte(0x66); /*MOV EBX, XMM7*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xfb); - } - - addbyte(0x66); /*PMULHW XMM5, XMM4*/ - addbyte(0x0f); - addbyte(0xe5); - addbyte(0xec); - addbyte(0x66); /*PUNPCKLWD XMM1, XMM5*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xcd); - addbyte(0x66); /*PSRAD XMM1, 8*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe1); - addbyte(8); - addbyte(0x66); /*PACKSSDW XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc9); - - if (tca_sub_clocal) - { - addbyte(0xc1); /*SHR EBX, 24*/ - addbyte(0xeb); - addbyte(24); - } - - if (tc_add_clocal) - { - addbyte(0x66); /*PADDW XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc8); - } - else if (tc_add_alocal) - { - addbyte(0xf2); /*PSHUFLW XMM4, XMM0, 3, 3, 3, 3*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xe0); - addbyte(0xff); - addbyte(0x66); /*PADDW XMM1, XMM4*/ - addbyte(0x0f); - addbyte(0xfc); - addbyte(0xcc); - } - if (tc_invert_output) - { - addbyte(0x66); /*PXOR XMM1, FF*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x0d); - addlong((uint32_t)(uintptr_t)&xmm_ff_w); - } - - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); - addbyte(0x66); /*PACKUSWB XMM3, XMM3*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xdb); - addbyte(0x66); /*PACKUSWB XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc9); - - if (tca_zero_other) - { - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - } - else - { - addbyte(0x66); /*MOV EAX, XMM3*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xd8); - addbyte(0xc1); /*SHR EAX, 24*/ - addbyte(0xe8); - addbyte(24); - } - if (tca_sub_clocal) - { - addbyte(0x29); /*SUB EAX, EBX*/ - addbyte(0xd8); - } - switch (tca_mselect) - { - case TCA_MSELECT_ZERO: - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - break; - case TCA_MSELECT_CLOCAL: - addbyte(0x66); /*MOV EBX, XMM7*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xfb); - addbyte(0xc1); /*SHR EBX, 24*/ - addbyte(0xeb); - addbyte(24); - break; - case TCA_MSELECT_AOTHER: - addbyte(0x66); /*MOV EBX, XMM3*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xdb); - addbyte(0xc1); /*SHR EBX, 24*/ - addbyte(0xeb); - addbyte(24); - break; - case TCA_MSELECT_ALOCAL: - addbyte(0x66); /*MOV EBX, XMM7*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xfb); - addbyte(0xc1); /*SHR EBX, 24*/ - addbyte(0xeb); - addbyte(24); - break; - case TCA_MSELECT_DETAIL: - addbyte(0xbb); /*MOV EBX, params->detail_bias[1]*/ - addlong(params->detail_bias[1]); - addbyte(0x2b); /*SUB EBX, state->lod*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, lod)); - addbyte(0xba); /*MOV EDX, params->detail_max[1]*/ - addlong(params->detail_max[1]); - addbyte(0xc1); /*SHL EBX, params->detail_scale[1]*/ - addbyte(0xe3); - addbyte(params->detail_scale[1]); - addbyte(0x39); /*CMP EBX, EDX*/ - addbyte(0xd3); - addbyte(0x0f); /*CMOVNL EBX, EDX*/ - addbyte(0x4d); - addbyte(0xda); - break; - case TCA_MSELECT_LOD_FRAC: - addbyte(0x8b); /*MOV EBX, state->lod_frac[0]*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, lod_frac[0])); - break; - } - if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) - { - addbyte(0x33); /*XOR EBX, i_00_ff_w[ECX*4]*/ - addbyte(0x1c); - addbyte(0x8d); - addlong((uint32_t)(uintptr_t)i_00_ff_w); - } - else if (!tca_reverse_blend) - { - addbyte(0x81); /*XOR EBX, 0xFF*/ - addbyte(0xf3); - addlong(0xff); - } - - addbyte(0x83); /*ADD EBX, 1*/ - addbyte(0xc3); - addbyte(1); - addbyte(0x0f); /*IMUL EAX, EBX*/ - addbyte(0xaf); - addbyte(0xc3); - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - addbyte(0xc1); /*SAR EAX, 8*/ - addbyte(0xf8); - addbyte(8); - if (tca_add_clocal || tca_add_alocal) - { - addbyte(0x66); /*MOV EBX, XMM7*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xfb); - addbyte(0xc1); /*SHR EBX, 24*/ - addbyte(0xeb); - addbyte(24); - addbyte(0x01); /*ADD EAX, EBX*/ - addbyte(0xd8); - } - addbyte(0x0f); /*CMOVS EAX, EDX*/ - addbyte(0x48); - addbyte(0xc2); - addbyte(0xba); /*MOV EDX, 0xff*/ - addlong(0xff); - addbyte(0x3d); /*CMP EAX, 0xff*/ - addlong(0xff); - addbyte(0x0f); /*CMOVA EAX, EDX*/ - addbyte(0x47); - addbyte(0xc2); - if (tca_invert_output) - { - addbyte(0x35); /*XOR EAX, 0xff*/ - addlong(0xff); - } - - addbyte(0x89); /*MOV state->tex_a[EDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_a)); - - addbyte(0xf3); /*MOVQ XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc1); - } - if (cc_mselect == CC_MSELECT_TEXRGB) - { - addbyte(0xf3); /*MOVD XMM4, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe0); - } - - if ((params->fbzMode & FBZ_CHROMAKEY)) - { - addbyte(0x66); /*MOVD EAX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc0); - addbyte(0x8b); /*MOV EBX, params->chromaKey[ESI]*/ - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, chromaKey)); - addbyte(0x31); /*XOR EBX, EAX*/ - addbyte(0xc3); - addbyte(0x81); /*AND EBX, 0xffffff*/ - addbyte(0xe3); - addlong(0xffffff); - addbyte(0x0f); /*JE skip*/ - addbyte(0x84); - chroma_skip_pos = block_pos; - addlong(0); - } - - if (voodoo->trexInit1[0] & (1 << 18)) - { - addbyte(0xb8); /*MOV EAX, tmuConfig*/ - addlong(voodoo->tmuConfig); - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - } - - if (params->alphaMode & ((1 << 0) | (1 << 4))) - { - /*EBX = a_other*/ - switch (a_sel) - { - case A_SEL_ITER_A: - addbyte(0x8b); /*MOV EBX, state->ia*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, ia)); - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xba); /*MOV EDX, 0xff*/ - addlong(0xff); - addbyte(0xc1); /*SAR EBX, 12*/ - addbyte(0xfb); - addbyte(12); - addbyte(0x0f); /*CMOVS EBX, EAX*/ - addbyte(0x48); - addbyte(0xd8); - addbyte(0x39); /*CMP EBX, EDX*/ - addbyte(0xd3); - addbyte(0x0f); /*CMOVA EBX, EDX*/ - addbyte(0x47); - addbyte(0xda); - break; - case A_SEL_TEX: - addbyte(0x8b); /*MOV EBX, state->tex_a*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tex_a)); - break; - case A_SEL_COLOR1: - addbyte(0x0f); /*MOVZX EBX, params->color1+3*/ - addbyte(0xb6); - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, color1)+3); - break; - default: - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - break; - } - /*ECX = a_local*/ - switch (cca_localselect) - { - case CCA_LOCALSELECT_ITER_A: - if (a_sel == A_SEL_ITER_A) - { - addbyte(0x89); /*MOV ECX, EBX*/ - addbyte(0xd9); - } - else - { - addbyte(0x8b); /*MOV ECX, state->ia*/ - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, ia)); - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xba); /*MOV EDX, 0xff*/ - addlong(0xff); - addbyte(0xc1);/*SAR ECX, 12*/ - addbyte(0xf9); - addbyte(12); - addbyte(0x0f); /*CMOVS ECX, EAX*/ - addbyte(0x48); - addbyte(0xc8); - addbyte(0x39); /*CMP ECX, EDX*/ - addbyte(0xd1); - addbyte(0x0f); /*CMOVA ECX, EDX*/ - addbyte(0x47); - addbyte(0xca); - } - break; - case CCA_LOCALSELECT_COLOR0: - addbyte(0x0f); /*MOVZX ECX, params->color0+3*/ - addbyte(0xb6); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, color0)+3); - break; - case CCA_LOCALSELECT_ITER_Z: - addbyte(0x8b); /*MOV ECX, state->z*/ - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, z)); - if (a_sel != A_SEL_ITER_A) - { - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xba); /*MOV EDX, 0xff*/ - addlong(0xff); - } - addbyte(0xc1);/*SAR ECX, 20*/ - addbyte(0xf9); - addbyte(20); - addbyte(0x0f); /*CMOVS ECX, EAX*/ - addbyte(0x48); - addbyte(0xc8); - addbyte(0x39); /*CMP ECX, EDX*/ - addbyte(0xd1); - addbyte(0x0f); /*CMOVA ECX, EDX*/ - addbyte(0x47); - addbyte(0xca); - break; - - default: - addbyte(0xb9); /*MOV ECX, 0xff*/ - addlong(0xff); - break; - } - - if (cca_zero_other) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x89); /*MOV EDX, EBX*/ - addbyte(0xda); - } - - if (cca_sub_clocal) - { - addbyte(0x29); /*SUB EDX, ECX*/ - addbyte(0xca); - } - } - - if (cc_sub_clocal || cc_mselect == 1 || cc_add == 1) - { - /*XMM1 = local*/ - if (!cc_localselect_override) - { - if (cc_localselect) - { - addbyte(0x66); /*MOVD XMM1, params->color0*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, color0)); - } - else - { - addbyte(0xf3); /*MOVDQU XMM1, ib*/ /* ir, ig and ib must be in same dqword!*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, ib)); - addbyte(0x66); /*PSRAD XMM1, 12*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe1); - addbyte(12); - addbyte(0x66); /*PACKSSDW XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc9); - addbyte(0x66); /*PACKUSWB XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc9); - } - } - else - { - addbyte(0xf6); /*TEST state->tex_a, 0x80*/ - addbyte(0x87); - addbyte(0x23); - addlong(offsetof(voodoo_state_t, tex_a)); - addbyte(0x80); - addbyte(0x74);/*JZ !cc_localselect*/ - addbyte(8+2); - addbyte(0x66); /*MOVD XMM1, params->color0*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, color0)); - addbyte(0xeb); /*JMP +*/ - addbyte(8+5+4+4); - /*!cc_localselect:*/ - addbyte(0xf3); /*MOVDQU XMM1, ib*/ /* ir, ig and ib must be in same dqword!*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, ib)); - addbyte(0x66); /*PSRAD XMM1, 12*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe1); - addbyte(12); - addbyte(0x66); /*PACKSSDW XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc9); - addbyte(0x66); /*PACKUSWB XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc9); - } - addbyte(0x66); /*PUNPCKLBW XMM1, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xca); - } - if (!cc_zero_other) - { - if (_rgb_sel == CC_LOCALSELECT_ITER_RGB) - { - addbyte(0xf3); /*MOVDQU XMM0, ib*/ /* ir, ig and ib must be in same dqword!*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, ib)); - addbyte(0x66); /*PSRAD XMM0, 12*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe0); - addbyte(12); - addbyte(0x66); /*PACKSSDW XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0); - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); - } - else if (_rgb_sel == CC_LOCALSELECT_TEX) - { -#if 0 - addbyte(0xf3); /*MOVDQU XMM0, state->tex_b*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_b)); - addbyte(0x66); /*PACKSSDW XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0); - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); -#endif - } - else if (_rgb_sel == CC_LOCALSELECT_COLOR1) - { - addbyte(0x66); /*MOVD XMM0, params->color1*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x86); - addlong(offsetof(voodoo_params_t, color1)); - } - else - { - /*MOVD XMM0, src_r*/ - } - addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc2); - if (cc_sub_clocal) - { - addbyte(0x66); /*PSUBW XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xc1); - } - } - else - { - addbyte(0x66); /*PXOR XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xc0); - if (cc_sub_clocal) - { - addbyte(0x66); /*PSUBW XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xc1); - } - } - - if (params->alphaMode & ((1 << 0) | (1 << 4))) - { - if (!(cca_mselect == 0 && cca_reverse_blend == 0)) - { - switch (cca_mselect) - { - case CCA_MSELECT_ALOCAL: - addbyte(0x89); /*MOV EAX, ECX*/ - addbyte(0xc8); - break; - case CCA_MSELECT_AOTHER: - addbyte(0x89); /*MOV EAX, EBX*/ - addbyte(0xd8); - break; - case CCA_MSELECT_ALOCAL2: - addbyte(0x89); /*MOV EAX, ECX*/ - addbyte(0xc8); - break; - case CCA_MSELECT_TEX: - addbyte(0x0f); /*MOVZX EAX, state->tex_a*/ - addbyte(0xb6); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_a)); - break; - - case CCA_MSELECT_ZERO: - default: - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - break; - } - if (!cca_reverse_blend) - { - addbyte(0x35); /*XOR EAX, 0xff*/ - addlong(0xff); - } - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(1); - addbyte(0x0f); /*IMUL EDX, EAX*/ - addbyte(0xaf); - addbyte(0xd0); - addbyte(0xc1); /*SHR EDX, 8*/ - addbyte(0xea); - addbyte(8); - } - } - - if ((params->alphaMode & ((1 << 0) | (1 << 4)))) - { - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - } - - if (!(cc_mselect == 0 && cc_reverse_blend == 0) && cc_mselect == CC_MSELECT_AOTHER) - { - /*Copy a_other to XMM3 before it gets modified*/ - addbyte(0x66); /*MOVD XMM3, EDX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xda); - addbyte(0xf2); /*PSHUFLW XMM3, XMM3, 0*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xdb); - addbyte(0x00); - } - - if (cca_add && (params->alphaMode & ((1 << 0) | (1 << 4)))) - { - addbyte(0x01); /*ADD EDX, ECX*/ - addbyte(0xca); - } - - if ((params->alphaMode & ((1 << 0) | (1 << 4)))) - { - addbyte(0x85); /*TEST EDX, EDX*/ - addbyte(0xd2); - addbyte(0x0f); /*CMOVS EDX, EAX*/ - addbyte(0x48); - addbyte(0xd0); - addbyte(0xb8); /*MOV EAX, 0xff*/ - addlong(0xff); - addbyte(0x81); /*CMP EDX, 0xff*/ - addbyte(0xfa); - addlong(0xff); - addbyte(0x0f); /*CMOVA EDX, EAX*/ - addbyte(0x47); - addbyte(0xd0); - if (cca_invert_output) - { - addbyte(0x81); /*XOR EDX, 0xff*/ - addbyte(0xf2); - addlong(0xff); - } - } - - if (!(cc_mselect == 0 && cc_reverse_blend == 0)) - { - switch (cc_mselect) - { - case CC_MSELECT_ZERO: - addbyte(0x66); /*PXOR XMM3, XMM3*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xdb); - break; - case CC_MSELECT_CLOCAL: - addbyte(0xf3); /*MOV XMM3, XMM1*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xd9); - break; - case CC_MSELECT_ALOCAL: - addbyte(0x66); /*MOVD XMM3, ECX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xd9); - addbyte(0xf2); /*PSHUFLW XMM3, XMM3, 0*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xdb); - addbyte(0x00); - break; - case CC_MSELECT_AOTHER: - /*Handled above*/ - break; - case CC_MSELECT_TEX: - addbyte(0x66); /*PINSRW XMM3, state->tex_a, 0*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tex_a)); - addbyte(0); - addbyte(0x66); /*PINSRW XMM3, state->tex_a, 1*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tex_a)); - addbyte(1); - addbyte(0x66); /*PINSRW XMM3, state->tex_a, 2*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tex_a)); - addbyte(2); - break; - case CC_MSELECT_TEXRGB: - addbyte(0x66); /*PUNPCKLBW XMM4, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xe2); - addbyte(0xf3); /*MOVQ XMM3, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xdc); - break; - default: - addbyte(0x66); /*PXOR XMM3, XMM3*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xdb); - break; - } - addbyte(0xf3); /*MOV XMM4, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe0); - if (!cc_reverse_blend) - { - addbyte(0x66); /*PXOR XMM3, 0xff*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_ff_w); - } - addbyte(0x66); /*PADDW XMM3, 1*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_01_w); - addbyte(0x66); /*PMULLW XMM0, XMM3*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xc3); - addbyte(0x66); /*PMULHW XMM4, XMM3*/ - addbyte(0x0f); - addbyte(0xe5); - addbyte(0xe3); - addbyte(0x66); /*PUNPCKLWD XMM0, XMM4*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xc4); - addbyte(0x66); /*PSRLD XMM0, 8*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe0); - addbyte(8); - addbyte(0x66); /*PACKSSDW XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0); - } - - if (cc_add == 1) - { - addbyte(0x66); /*PADDW XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc1); - } - - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); - - if (cc_invert_output) - { - addbyte(0x66); /*PXOR XMM0, 0xff*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_ff_b); - } - - if (params->fogMode & FOG_ENABLE) - { - if (params->fogMode & FOG_CONSTANT) - { - addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, fogColor)); - addbyte(0x66); /*PADDUSB XMM0, XMM3*/ - addbyte(0x0f); - addbyte(0xdc); - addbyte(0xc3); - } - else - { - addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc2); - - if (!(params->fogMode & FOG_ADD)) - { - addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, fogColor)); - addbyte(0x66); /*PUNPCKLBW XMM3, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xda); - } - else - { - addbyte(0x66); /*PXOR XMM3, XMM3*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xdb); - } - - if (!(params->fogMode & FOG_MULT)) - { - addbyte(0x66); /*PSUBW XMM3, XMM0*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xd8); - } - - /*Divide by 2 to prevent overflow on multiply*/ - addbyte(0x66); /*PSRAW XMM3, 1*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xe3); - addbyte(1); - - switch (params->fogMode & (FOG_Z|FOG_ALPHA)) - { - case 0: - addbyte(0x8b); /*MOV EBX, state->w_depth[EDI]*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, w_depth)); - addbyte(0x89); /*MOV EAX, EBX*/ - addbyte(0xd8); - addbyte(0xc1); /*SHR EBX, 10*/ - addbyte(0xeb); - addbyte(10); - addbyte(0xc1); /*SHR EAX, 2*/ - addbyte(0xe8); - addbyte(2); - addbyte(0x83); /*AND EBX, 0x3f*/ - addbyte(0xe3); - addbyte(0x3f); - addbyte(0x25); /*AND EAX, 0xff*/ - addlong(0xff); - addbyte(0xf6); /*MUL params->fogTable+1[ESI+EBX*2]*/ - addbyte(0xa4); - addbyte(0x5e); - addlong(offsetof(voodoo_params_t, fogTable)+1); - addbyte(0x0f); /*MOVZX EBX, params->fogTable[ESI+EBX*2]*/ - addbyte(0xb6); - addbyte(0x9c); - addbyte(0x5e); - addlong(offsetof(voodoo_params_t, fogTable)); - addbyte(0xc1); /*SHR EAX, 10*/ - addbyte(0xe8); - addbyte(10); - addbyte(0x01); /*ADD EAX, EBX*/ - addbyte(0xd8); -/* int fog_idx = (w_depth >> 10) & 0x3f; - - fog_a = params->fogTable[fog_idx].fog; - fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10;*/ - break; - - case FOG_Z: - addbyte(0x8b); /*MOV EAX, state->z[EDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, z)); - addbyte(0xc1); /*SHR EAX, 12*/ - addbyte(0xe8); - addbyte(12); - addbyte(0x25); /*AND EAX, 0xff*/ - addlong(0xff); -// fog_a = (z >> 20) & 0xff; - break; - - case FOG_ALPHA: - addbyte(0x8b); /*MOV EAX, state->ia[EDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, ia)); - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - addbyte(0xc1); /*SAR EAX, 12*/ - addbyte(0xf8); - addbyte(12); - addbyte(0x0f); /*CMOVS EAX, EBX*/ - addbyte(0x48); - addbyte(0xc3); - addbyte(0xbb); /*MOV EBX, 0xff*/ - addlong(0xff); - addbyte(0x3d); /*CMP EAX, 0xff*/ - addlong(0xff); - addbyte(0x0f); /*CMOVAE EAX, EBX*/ - addbyte(0x43); - addbyte(0xc3); -// fog_a = CLAMP(ia >> 12); - break; - - case FOG_W: - addbyte(0x8b); /*MOV EAX, state->w[EDI]+4*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, w)+4); - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - addbyte(0x09); /*OR EAX, EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*CMOVS EAX, EBX*/ - addbyte(0x48); - addbyte(0xc3); - addbyte(0xbb); /*MOV EBX, 0xff*/ - addlong(0xff); - addbyte(0x3d); /*CMP EAX, 0xff*/ - addlong(0xff); - addbyte(0x0f); /*CMOVAE EAX, EBX*/ - addbyte(0x43); - addbyte(0xc3); -// fog_a = CLAMP(w >> 32); - break; - } - addbyte(0x01); /*ADD EAX, EAX*/ - addbyte(0xc0); - - addbyte(0x66); /*PMULLW XMM3, alookup+4[EAX*8]*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x1c); - addbyte(0xc5); - addlong(((uintptr_t)alookup) + 16); - addbyte(0x66); /*PSRAW XMM3, 7*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xe3); - addbyte(7); - - if (params->fogMode & FOG_MULT) - { - addbyte(0xf3); /*MOV XMM0, XMM3*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc3); - } - else - { - addbyte(0x66); /*PADDW XMM0, XMM3*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc3); - } - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); - } - } - - if ((params->alphaMode & 1) && (alpha_func != AFUNC_NEVER) && (alpha_func != AFUNC_ALWAYS)) - { - addbyte(0x0f); /*MOVZX ECX, params->alphaMode+3*/ - addbyte(0xb6); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, alphaMode) + 3); - addbyte(0x39); /*CMP EDX, ECX*/ - addbyte(0xca); - - switch (alpha_func) - { - case AFUNC_LESSTHAN: - addbyte(0x0f); /*JAE skip*/ - addbyte(0x83); - a_skip_pos = block_pos; - addlong(0); - break; - case AFUNC_EQUAL: - addbyte(0x0f); /*JNE skip*/ - addbyte(0x85); - a_skip_pos = block_pos; - addlong(0); - break; - case AFUNC_LESSTHANEQUAL: - addbyte(0x0f); /*JA skip*/ - addbyte(0x87); - a_skip_pos = block_pos; - addlong(0); - break; - case AFUNC_GREATERTHAN: - addbyte(0x0f); /*JBE skip*/ - addbyte(0x86); - a_skip_pos = block_pos; - addlong(0); - break; - case AFUNC_NOTEQUAL: - addbyte(0x0f); /*JE skip*/ - addbyte(0x84); - a_skip_pos = block_pos; - addlong(0); - break; - case AFUNC_GREATERTHANEQUAL: - addbyte(0x0f); /*JB skip*/ - addbyte(0x82); - a_skip_pos = block_pos; - addlong(0); - break; - } - } - else if ((params->alphaMode & 1) && (alpha_func == AFUNC_NEVER)) - { - addbyte(0xC3); /*RET*/ - } - - if (params->alphaMode & (1 << 4)) - { - addbyte(0x49); /*MOV R8, rgb565*/ - addbyte(0xb8); - addquad((uintptr_t)rgb565); - addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, x)); - addbyte(0x48); /*MOV RBP, fb_mem*/ - addbyte(0x8b); - addbyte(0xaf); - addlong(offsetof(voodoo_state_t, fb_mem)); - addbyte(0x01); /*ADD EDX, EDX*/ - addbyte(0xd2); - addbyte(0x0f); /*MOVZX EAX, [RBP+RAX*2]*/ - addbyte(0xb7); - addbyte(0x44); - addbyte(0x45); - addbyte(0); - addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc2); - addbyte(0x66); /*MOVD XMM4, rgb565[EAX*4]*/ - addbyte(0x41); - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x24); - addbyte(0x80); - addbyte(0x66); /*PUNPCKLBW XMM4, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xe2); - addbyte(0xf3); /*MOV XMM6, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xf4); - - switch (dest_afunc) - { - case AFUNC_AZERO: - addbyte(0x66); /*PXOR XMM4, XMM4*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xe4); - break; - case AFUNC_ASRC_ALPHA: - addbyte(0x66); /*PMULLW XMM4, alookup[EDX*8]*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x24); - addbyte(0xd5); - addlong((uint32_t)(uintptr_t)alookup); - addbyte(0xf3); /*MOVQ XMM5, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM4, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xe5); - addbyte(0x66); /*PSRLW XMM4, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd4); - addbyte(8); - break; - case AFUNC_A_COLOR: - addbyte(0x66); /*PMULLW XMM4, XMM0*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xe0); - addbyte(0xf3); /*MOVQ XMM5, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM4, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xe5); - addbyte(0x66); /*PSRLW XMM4, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd4); - addbyte(8); - break; - case AFUNC_ADST_ALPHA: - break; - case AFUNC_AONE: - break; - case AFUNC_AOMSRC_ALPHA: - addbyte(0x66); /*PMULLW XMM4, aminuslookup[EDX*8]*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x24); - addbyte(0xd5); - addlong((uint32_t)(uintptr_t)aminuslookup); - addbyte(0xf3); /*MOVQ XMM5, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM4, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xe5); - addbyte(0x66); /*PSRLW XMM4, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd4); - addbyte(8); - break; - case AFUNC_AOM_COLOR: - addbyte(0xf3); /*MOVQ XMM5, xmm_ff_w*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x2c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_ff_w); - addbyte(0x66); /*PSUBW XMM5, XMM0*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xe8); - addbyte(0x66); /*PMULLW XMM4, XMM5*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xe5); - addbyte(0xf3); /*MOVQ XMM5, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM4, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xe5); - addbyte(0x66); /*PSRLW XMM4, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd4); - addbyte(8); - break; - case AFUNC_AOMDST_ALPHA: - addbyte(0x66); /*PXOR XMM4, XMM4*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xe4); - break; - case AFUNC_ASATURATE: - addbyte(0x66); /*PMULLW XMM4, minus_254*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x24); - addbyte(0xd5); - addlong((uint32_t)(uintptr_t)&minus_254); - addbyte(0xf3); /*MOVQ XMM5, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM4, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xe5); - addbyte(0x66); /*PSRLW XMM4, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd4); - addbyte(8); - } - - switch (src_afunc) - { - case AFUNC_AZERO: - addbyte(0x66); /*PXOR XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xc0); - break; - case AFUNC_ASRC_ALPHA: - addbyte(0x66); /*PMULLW XMM0, alookup[EDX*8]*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x04); - addbyte(0xd5); - addlong((uint32_t)(uintptr_t)alookup); - addbyte(0xf3); /*MOVQ XMM5, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe8); - addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM0, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc5); - addbyte(0x66); /*PSRLW XMM0, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd0); - addbyte(8); - break; - case AFUNC_A_COLOR: - addbyte(0x66); /*PMULLW XMM0, XMM6*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xc6); - addbyte(0xf3); /*MOVQ XMM5, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe8); - addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM0, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc5); - addbyte(0x66); /*PSRLW XMM0, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd0); - addbyte(8); - break; - case AFUNC_ADST_ALPHA: - break; - case AFUNC_AONE: - break; - case AFUNC_AOMSRC_ALPHA: - addbyte(0x66); /*PMULLW XMM0, aminuslookup[EDX*8]*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x04); - addbyte(0xd5); - addlong((uint32_t)(uintptr_t)aminuslookup); - addbyte(0xf3); /*MOVQ XMM5, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe8); - addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM0, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc5); - addbyte(0x66); /*PSRLW XMM0, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd0); - addbyte(8); - break; - case AFUNC_AOM_COLOR: - addbyte(0xf3); /*MOVQ XMM5, xmm_ff_w*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x2c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_ff_w); - addbyte(0x66); /*PSUBW XMM5, XMM6*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xee); - addbyte(0x66); /*PMULLW XMM0, XMM5*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xc5); - addbyte(0xf3); /*MOVQ XMM5, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe8); - addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM0, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc5); - addbyte(0x66); /*PSRLW XMM0, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd0); - addbyte(8); - break; - case AFUNC_AOMDST_ALPHA: - addbyte(0x66); /*PXOR XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xc0); - break; - case AFUNC_ACOLORBEFOREFOG: - break; - } - - addbyte(0x66); /*PADDW XMM0, XMM4*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc4); - - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); - } - - addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ - addbyte(0x97); - addlong(offsetof(voodoo_state_t, x)); - - addbyte(0x66); /*MOV EAX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc0); - - if (params->fbzMode & FBZ_RGB_WMASK) - { - if (dither) - { - addbyte(0x49); /*MOV R8, dither_rb*/ - addbyte(0xb8); - addquad(dither2x2 ? (uintptr_t)dither_rb2x2 : (uintptr_t)dither_rb); - addbyte(0x4c); /*MOV ESI, real_y (R14)*/ - addbyte(0x89); - addbyte(0xf6); - addbyte(0x0f); /*MOVZX EBX, AH*/ /*G*/ - addbyte(0xb6); - addbyte(0xdc); - if (dither2x2) - { - addbyte(0x83); /*AND EDX, 1*/ - addbyte(0xe2); - addbyte(1); - addbyte(0x83); /*AND ESI, 1*/ - addbyte(0xe6); - addbyte(1); - addbyte(0xc1); /*SHL EBX, 2*/ - addbyte(0xe3); - addbyte(2); - } - else - { - addbyte(0x83); /*AND EDX, 3*/ - addbyte(0xe2); - addbyte(3); - addbyte(0x83); /*AND ESI, 3*/ - addbyte(0xe6); - addbyte(3); - addbyte(0xc1); /*SHL EBX, 4*/ - addbyte(0xe3); - addbyte(4); - } - addbyte(0x0f); /*MOVZX ECX, AL*/ /*R*/ - addbyte(0xb6); - addbyte(0xc8); - if (dither2x2) - { - addbyte(0xc1); /*SHR EAX, 14*/ - addbyte(0xe8); - addbyte(14); - addbyte(0x8d); /*LEA ESI, RDX+RSI*2*/ - addbyte(0x34); - addbyte(0x72); - } - else - { - addbyte(0xc1); /*SHR EAX, 12*/ - addbyte(0xe8); - addbyte(12); - addbyte(0x8d); /*LEA ESI, RDX+RSI*4*/ - addbyte(0x34); - addbyte(0xb2); - } - addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ - addbyte(0x97); - addlong(offsetof(voodoo_state_t, x)); - addbyte(0x4c); /*ADD RSI, R8*/ - addbyte(0x01); - addbyte(0xc6); - if (dither2x2) - { - addbyte(0xc1); /*SHL ECX, 2*/ - addbyte(0xe1); - addbyte(2); - addbyte(0x25); /*AND EAX, 0x3fc*/ /*B*/ - addlong(0x3fc); - } - else - { - addbyte(0xc1); /*SHL ECX, 4*/ - addbyte(0xe1); - addbyte(4); - addbyte(0x25); /*AND EAX, 0xff0*/ /*B*/ - addlong(0xff0); - } - addbyte(0x0f); /*MOVZX EBX, dither_g[EBX+ESI]*/ - addbyte(0xb6); - addbyte(0x9c); - addbyte(0x1e); - addlong(dither2x2 ? ((uintptr_t)dither_g2x2 - (uintptr_t)dither_rb2x2) : ((uintptr_t)dither_g - (uintptr_t)dither_rb)); - addbyte(0x0f); /*MOVZX ECX, dither_rb[RCX+RSI]*/ - addbyte(0xb6); - addbyte(0x0c); - addbyte(0x0e); - addbyte(0x0f); /*MOVZX EAX, dither_rb[RAX+RSI]*/ - addbyte(0xb6); - addbyte(0x04); - addbyte(0x06); - addbyte(0xc1); /*SHL EBX, 5*/ - addbyte(0xe3); - addbyte(5); - addbyte(0xc1); /*SHL EAX, 11*/ - addbyte(0xe0); - addbyte(11); - addbyte(0x09); /*OR EAX, EBX*/ - addbyte(0xd8); - addbyte(0x09); /*OR EAX, ECX*/ - addbyte(0xc8); - } - else - { - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - addbyte(0x0f); /*MOVZX ECX, AH*/ - addbyte(0xb6); - addbyte(0xcc); - addbyte(0xc1); /*SHR EAX, 3*/ - addbyte(0xe8); - addbyte(3); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0xc1); /*SHL ECX, 3*/ - addbyte(0xe1); - addbyte(3); - addbyte(0x81); /*AND EAX, 0x001f*/ - addbyte(0xe0); - addlong(0x001f); - addbyte(0x81); /*AND EBX, 0xf800*/ - addbyte(0xe3); - addlong(0xf800); - addbyte(0x81); /*AND ECX, 0x07e0*/ - addbyte(0xe1); - addlong(0x07e0); - addbyte(0x09); /*OR EAX, EBX*/ - addbyte(0xd8); - addbyte(0x09); /*OR EAX, ECX*/ - addbyte(0xc8); - } - addbyte(0x48); /*MOV RSI, fb_mem*/ - addbyte(0x8b); - addbyte(0xb7); - addlong(offsetof(voodoo_state_t, fb_mem)); - addbyte(0x66); /*MOV [ESI+EDX*2], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x56); - } - - if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) - { - addbyte(0x66); /*MOV AX, new_depth*/ - addbyte(0x8b); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, new_depth)); - addbyte(0x48); /*MOV RSI, aux_mem*/ - addbyte(0x8b); - addbyte(0xb7); - addlong(offsetof(voodoo_state_t, aux_mem)); - addbyte(0x66); /*MOV [ESI+EDX*2], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x56); - } - - if (z_skip_pos) - *(uint32_t *)&code_block[z_skip_pos] = (block_pos - z_skip_pos) - 4; - if (a_skip_pos) - *(uint32_t *)&code_block[a_skip_pos] = (block_pos - a_skip_pos) - 4; - if (chroma_skip_pos) - *(uint32_t *)&code_block[chroma_skip_pos] = (block_pos - chroma_skip_pos) - 4; - - addbyte(0x4c); /*MOV RSI, R15*/ - addbyte(0x89); - addbyte(0xfe); - - addbyte(0xf3); /*MOVDQU XMM1, state->ib[EDI]*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, ib)); - addbyte(0xf3); /*MOVDQU XMM3, state->tmu0_s[EDI]*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tmu0_s)); - addbyte(0xf3); /*MOVQ XMM4, state->tmu0_w[EDI]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xa7); - addlong(offsetof(voodoo_state_t, tmu0_w)); - addbyte(0xf3); /*MOVDQU XMM0, params->dBdX[ESI]*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x86); - addlong(offsetof(voodoo_params_t, dBdX)); - addbyte(0x8b); /*MOV EAX, params->dZdX[ESI]*/ - addbyte(0x86); - addlong(offsetof(voodoo_params_t, dZdX)); - addbyte(0xf3); /*MOVDQU XMM5, params->tmu[0].dSdX[ESI]*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0xae); - addlong(offsetof(voodoo_params_t, tmu[0].dSdX)); - addbyte(0xf3); /*MOVQ XMM6, params->tmu[0].dWdX[ESI]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xb6); - addlong(offsetof(voodoo_params_t, tmu[0].dWdX)); - - if (state->xdir > 0) - { - addbyte(0x66); /*PADDD XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0xfe); - addbyte(0xc8); - } - else - { - addbyte(0x66); /*PSUBD XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0xfa); - addbyte(0xc8); - } - - addbyte(0xf3); /*MOVQ XMM0, state->w*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, w)); - addbyte(0xf3); /*MOVDQU state->ib, XMM1*/ - addbyte(0x0f); - addbyte(0x7f); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, ib)); - addbyte(0xf3); /*MOVQ XMM7, params->dWdX*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xbe); - addlong(offsetof(voodoo_params_t, dWdX)); - - if (state->xdir > 0) - { - addbyte(0x66); /*PADDQ XMM3, XMM5*/ - addbyte(0x0f); - addbyte(0xd4); - addbyte(0xdd); - addbyte(0x66); /*PADDQ XMM4, XMM6*/ - addbyte(0x0f); - addbyte(0xd4); - addbyte(0xe6); - addbyte(0x66); /*PADDQ XMM0, XMM7*/ - addbyte(0x0f); - addbyte(0xd4); - addbyte(0xc7); - addbyte(0x01); /*ADD state->z[EDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, z)); - } - else - { - addbyte(0x66); /*PSUBQ XMM3, XMM5*/ - addbyte(0x0f); - addbyte(0xfb); - addbyte(0xdd); - addbyte(0x66); /*PSUBQ XMM4, XMM6*/ - addbyte(0x0f); - addbyte(0xfb); - addbyte(0xe6); - addbyte(0x66); /*PSUBQ XMM0, XMM7*/ - addbyte(0x0f); - addbyte(0xfb); - addbyte(0xc7); - addbyte(0x29); /*SUB state->z[EDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, z)); - } - - if (voodoo->dual_tmus) - { - addbyte(0xf3); /*MOVDQU XMM5, params->tmu[1].dSdX[ESI]*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0xae); - addlong(offsetof(voodoo_params_t, tmu[1].dSdX)); - addbyte(0xf3); /*MOVQ XMM6, params->tmu[1].dWdX[ESI]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xb6); - addlong(offsetof(voodoo_params_t, tmu[1].dWdX)); - } - - addbyte(0xf3); /*MOVDQU state->tmu0_s, XMM3*/ - addbyte(0x0f); - addbyte(0x7f); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tmu0_s)); - addbyte(0x66); /*MOVQ state->tmu0_w, XMM4*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0xa7); - addlong(offsetof(voodoo_state_t, tmu0_w)); - addbyte(0x66); /*MOVQ state->w, XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, w)); - - if (voodoo->dual_tmus) - { - addbyte(0xf3); /*MOVDQU XMM3, state->tmu1_s[EDI]*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tmu1_s)); - addbyte(0xf3); /*MOVQ XMM4, state->tmu1_w[EDI]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xa7); - addlong(offsetof(voodoo_state_t, tmu1_w)); - - if (state->xdir > 0) - { - addbyte(0x66); /*PADDQ XMM3, XMM5*/ - addbyte(0x0f); - addbyte(0xd4); - addbyte(0xdd); - addbyte(0x66); /*PADDQ XMM4, XMM6*/ - addbyte(0x0f); - addbyte(0xd4); - addbyte(0xe6); - } - else - { - addbyte(0x66); /*PSUBQ XMM3, XMM5*/ - addbyte(0x0f); - addbyte(0xfb); - addbyte(0xdd); - addbyte(0x66); /*PSUBQ XMM4, XMM6*/ - addbyte(0x0f); - addbyte(0xfb); - addbyte(0xe6); - } - - addbyte(0xf3); /*MOVDQU state->tmu1_s, XMM3*/ - addbyte(0x0f); - addbyte(0x7f); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tmu1_s)); - addbyte(0x66); /*MOVQ state->tmu1_w, XMM4*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0xa7); - addlong(offsetof(voodoo_state_t, tmu1_w)); - } - - addbyte(0x83); /*ADD state->pixel_count[EDI], 1*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, pixel_count)); - addbyte(1); - - if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) - { - if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || - (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) - { - addbyte(0x83); /*ADD state->texel_count[EDI], 1*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, texel_count)); - addbyte(1); - } - else - { - addbyte(0x83); /*ADD state->texel_count[EDI], 2*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, texel_count)); - addbyte(2); - } - } - - addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, x)); - - if (state->xdir > 0) - { - addbyte(0x83); /*ADD state->x[EDI], 1*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, x)); - addbyte(1); - } - else - { - addbyte(0x83); /*SUB state->x[EDI], 1*/ - addbyte(0xaf); - addlong(offsetof(voodoo_state_t, x)); - addbyte(1); - } - - addbyte(0x3b); /*CMP EAX, state->x2[EDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, x2)); - addbyte(0x0f); /*JNZ loop_jump_pos*/ - addbyte(0x85); - addlong(loop_jump_pos - (block_pos + 4)); - - addbyte(0x41); /*POP R15*/ - addbyte(0x5f); - addbyte(0x41); /*POP R14*/ - addbyte(0x5e); - addbyte(0x5b); /*POP RBX*/ - addbyte(0x5e); /*POP RSI*/ - addbyte(0x5f); /*POP RDI*/ - addbyte(0x5d); /*POP RBP*/ - - addbyte(0xC3); /*RET*/ -} -static int voodoo_recomp = 0; -static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even) -{ - int c; - int b = last_block[odd_even]; - voodoo_x86_data_t *voodoo_x86_data = voodoo->codegen_data; - voodoo_x86_data_t *data; - - for (c = 0; c < 8; c++) - { - data = &voodoo_x86_data[odd_even + c*2]; //&voodoo_x86_data[odd_even][b]; - - if (state->xdir == data->xdir && - params->alphaMode == data->alphaMode && - params->fbzMode == data->fbzMode && - params->fogMode == data->fogMode && - params->fbzColorPath == data->fbzColorPath && - (voodoo->trexInit1[0] & (1 << 18)) == data->trexInit1 && - params->textureMode[0] == data->textureMode[0] && - params->textureMode[1] == data->textureMode[1] && - (params->tLOD[0] & LOD_MASK) == data->tLOD[0] && - (params->tLOD[1] & LOD_MASK) == data->tLOD[1]) - { - last_block[odd_even] = b; - return data->code_block; - } - - b = (b + 1) & 7; - } -voodoo_recomp++; - data = &voodoo_x86_data[odd_even + next_block_to_write[odd_even]*2]; -// code_block = data->code_block; - - voodoo_generate(data->code_block, voodoo, params, state, depth_op); - - data->xdir = state->xdir; - data->alphaMode = params->alphaMode; - data->fbzMode = params->fbzMode; - data->fogMode = params->fogMode; - data->fbzColorPath = params->fbzColorPath; - data->trexInit1 = voodoo->trexInit1[0] & (1 << 18); - data->textureMode[0] = params->textureMode[0]; - data->textureMode[1] = params->textureMode[1]; - data->tLOD[0] = params->tLOD[0] & LOD_MASK; - data->tLOD[1] = params->tLOD[1] & LOD_MASK; - - next_block_to_write[odd_even] = (next_block_to_write[odd_even] + 1) & 7; - - return data->code_block; -} - -static void voodoo_codegen_init(voodoo_t *voodoo) -{ - int c; -#ifdef __linux__ - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); -#endif - -#if WIN64 - voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2, MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else - voodoo->codegen_data = malloc(sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2); -#endif - -#ifdef __linux__ - start = (void *)((long)voodoo->codegen_data & pagemask); - len = ((sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2) + pagesize) & pagemask; - if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - { - perror("mprotect"); - exit(-1); - } -#endif - - for (c = 0; c < 256; c++) - { - int d[4]; - int _ds = c & 0xf; - int dt = c >> 4; - - alookup[c] = _mm_set_epi32(0, 0, c | (c << 16), c | (c << 16)); - aminuslookup[c] = _mm_set_epi32(0, 0, (255-c) | ((255-c) << 16), (255-c) | ((255-c) << 16)); - - d[0] = (16 - _ds) * (16 - dt); - d[1] = _ds * (16 - dt); - d[2] = (16 - _ds) * dt; - d[3] = _ds * dt; - - bilinear_lookup[c*2] = _mm_set_epi32(d[1] | (d[1] << 16), d[1] | (d[1] << 16), d[0] | (d[0] << 16), d[0] | (d[0] << 16)); - bilinear_lookup[c*2 + 1] = _mm_set_epi32(d[3] | (d[3] << 16), d[3] | (d[3] << 16), d[2] | (d[2] << 16), d[2] | (d[2] << 16)); - } - alookup[256] = _mm_set_epi32(0, 0, 256 | (256 << 16), 256 | (256 << 16)); - xmm_00_ff_w[0] = _mm_set_epi32(0, 0, 0, 0); - xmm_00_ff_w[1] = _mm_set_epi32(0, 0, 0xff | (0xff << 16), 0xff | (0xff << 16)); -} - -static void voodoo_codegen_close(voodoo_t *voodoo) -{ -#if WIN64 - VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); -#else - free(voodoo->codegen_data); -#endif -} - diff --git a/backup code/video - Cópia/vid_voodoo_codegen_x86.h b/backup code/video - Cópia/vid_voodoo_codegen_x86.h deleted file mode 100644 index 8e5f5f38d..000000000 --- a/backup code/video - Cópia/vid_voodoo_codegen_x86.h +++ /dev/null @@ -1,3335 +0,0 @@ -/*Registers : - - alphaMode - fbzMode & 0x1f3fff - fbzColorPath -*/ - -#ifdef __linux__ -# include -# include -#endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 -# include -#endif - -#include - -#define BLOCK_NUM 8 -#define BLOCK_MASK (BLOCK_NUM-1) -#define BLOCK_SIZE 8192 - -#define LOD_MASK (LOD_TMIRROR_S | LOD_TMIRROR_T) - -typedef struct voodoo_x86_data_t -{ - uint8_t code_block[BLOCK_SIZE]; - int xdir; - uint32_t alphaMode; - uint32_t fbzMode; - uint32_t fogMode; - uint32_t fbzColorPath; - uint32_t textureMode[2]; - uint32_t tLOD[2]; - uint32_t trexInit1; -} voodoo_x86_data_t; - -static int last_block[2] = {0, 0}; -static int next_block_to_write[2] = {0, 0}; - -#define addbyte(val) \ - code_block[block_pos++] = val; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") - -#define addword(val) \ - *(uint16_t *)&code_block[block_pos] = val; \ - block_pos += 2; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") - -#define addlong(val) \ - *(uint32_t *)&code_block[block_pos] = val; \ - block_pos += 4; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") - -#define addquad(val) \ - *(uint64_t *)&code_block[block_pos] = val; \ - block_pos += 8; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") - - -static __m128i xmm_01_w;// = 0x0001000100010001ull; -static __m128i xmm_ff_w;// = 0x00ff00ff00ff00ffull; -static __m128i xmm_ff_b;// = 0x00000000ffffffffull; - -static uint32_t zero = 0; -static double const_1_48 = (double)(1ull << 4); - -static __m128i alookup[257], aminuslookup[256]; -static __m128i minus_254;// = 0xff02ff02ff02ff02ull; -static __m128i bilinear_lookup[256*2]; -static __m128i xmm_00_ff_w[2]; -static uint32_t i_00_ff_w[2] = {0, 0xff}; - -static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int block_pos, int tmu) -{ - if (params->textureMode[tmu] & 1) - { - addbyte(0xdf); /*FILDq state->tmu0_w*/ - addbyte(0xaf); - addlong(tmu ? offsetof(voodoo_state_t, tmu1_w) : offsetof(voodoo_state_t, tmu0_w)); - addbyte(0xdd); /*FLDq const_1_48*/ - addbyte(0x05); - addlong((uint32_t)&const_1_48); - addbyte(0xde); /*FDIV ST(1)*/ - addbyte(0xf1); - addbyte(0xdf); /*FILDq state->tmu0_s*/ - addbyte(0xaf); - addlong(tmu ? offsetof(voodoo_state_t, tmu1_s) : offsetof(voodoo_state_t, tmu0_s)); - addbyte(0xdf); /*FILDq state->tmu0_t*/ /*ST(0)=t, ST(1)=s, ST(2)=1/w*/ - addbyte(0xaf); - addlong(tmu ? offsetof(voodoo_state_t, tmu1_t) : offsetof(voodoo_state_t, tmu0_t)); - addbyte(0xd9); /*FXCH ST(1)*/ /*ST(0)=s, ST(1)=t, ST(2)=1/w*/ - addbyte(0xc9); - addbyte(0xd8); /*FMUL ST(2)*/ /*ST(0)=s/w, ST(1)=t, ST(2)=1/w*/ - addbyte(0xca); - addbyte(0xd9); /*FXCH ST(1)*/ /*ST(0)=t, ST(1)=s/w, ST(2)=1/w*/ - addbyte(0xc9); - addbyte(0xd8); /*FMUL ST(2)*/ /*ST(0)=t/w, ST(1)=s/w, ST(2)=1/w*/ - addbyte(0xca); - addbyte(0xd9); /*FXCH ST(2)*/ /*ST(0)=1/w, ST(1)=s/w, ST(2)=t/w*/ - addbyte(0xca); - addbyte(0xd9); /*FSTPs log_temp*/ /*ST(0)=s/w, ST(1)=t/w*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, log_temp)); - addbyte(0xdf); /*FSITPq state->tex_s*/ - addbyte(0xbf); - addlong(offsetof(voodoo_state_t, tex_s)); - addbyte(0x8b); /*MOV EAX, log_temp*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, log_temp)); - addbyte(0xdf); /*FSITPq state->tex_t*/ - addbyte(0xbf); - addlong(offsetof(voodoo_state_t, tex_t)); - addbyte(0xc1); /*SHR EAX, 23-8*/ - addbyte(0xe8); - addbyte(15); - addbyte(0x0f); /*MOVZX EBX, AL*/ - addbyte(0xb6); - addbyte(0xd8); - addbyte(0x25); /*AND EAX, 0xff00*/ - addlong(0xff00); - addbyte(0x2d); /*SUB EAX, (127-44)<<8*/ - addlong((127-44+19) << 8); - addbyte(0x0f); /*MOVZX EBX, logtable[EBX]*/ - addbyte(0xb6); - addbyte(0x9b); - addlong((uint32_t)logtable); - addbyte(0x09); /*OR EAX, EBX*/ - addbyte(0xd8); - addbyte(0x03); /*ADD EAX, state->lod*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tmu[tmu].lod)); - addbyte(0x3b); /*CMP EAX, state->lod_min*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_min[tmu])); - addbyte(0x0f); /*CMOVL EAX, state->lod_min*/ - addbyte(0x4c); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_min[tmu])); - addbyte(0x3b); /*CMP EAX, state->lod_max*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_max[tmu])); - addbyte(0x0f); /*CMOVNL EAX, state->lod_max*/ - addbyte(0x4d); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_max[tmu])); - addbyte(0x0f); /*MOVZX EBX, AL*/ - addbyte(0xb6); - addbyte(0xd8); - addbyte(0xc1); /*SHR EAX, 8*/ - addbyte(0xe8); - addbyte(8); - addbyte(0x89); /*MOV state->lod_frac[tmu], EBX*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, lod_frac[tmu])); - addbyte(0x89); /*MOV state->lod, EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod)); - } - else - { - addbyte(0xf3); /*MOVQ XMM4, state->tmu0_s*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xa7); - addlong(tmu ? offsetof(voodoo_state_t, tmu1_s) : offsetof(voodoo_state_t, tmu0_s)); - addbyte(0xf3); /*MOVQ XMM5, state->tmu0_t*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xaf); - addlong(tmu ? offsetof(voodoo_state_t, tmu1_t) : offsetof(voodoo_state_t, tmu0_t)); - addbyte(0xc7); /*MOV state->lod[tmu], 0*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_frac[tmu])); - addlong(0); - addbyte(0x8b); /*MOV EAX, state->lod_min*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_min[tmu])); - addbyte(0x66); /*SHRQ XMM4, 28*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xd4); - addbyte(28); - addbyte(0x66); /*SHRQ XMM5, 28*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xd5); - addbyte(28); - addbyte(0x0f); /*MOVZX EBX, AL*/ - addbyte(0xb6); - addbyte(0xd8); - addbyte(0xc1); /*SHR EAX, 8*/ - addbyte(0xe8); - addbyte(8); - addbyte(0x66); /*MOVQ state->tex_s, XMM4*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0xa7); - addlong(offsetof(voodoo_state_t, tex_s)); - addbyte(0x66); /*MOVQ state->tex_t, XMM5*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0xaf); - addlong(offsetof(voodoo_state_t, tex_t)); - addbyte(0x89); /*MOV state->lod_frac[tmu], EBX*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, lod_frac[tmu])); - addbyte(0x89); /*MOV state->lod, EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod)); - } - /*EAX = state->lod*/ - if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) - { - if (voodoo->bilinear_enabled && (params->textureMode[tmu] & 6)) - { - addbyte(0x8b); /*MOV ECX, state->tex_lod[tmu]*/ - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, tex_lod[tmu])); - addbyte(0xb2); /*MOV DL, 8*/ - addbyte(8); - addbyte(0x8b); /*MOV ECX, [ECX+EAX*4]*/ - addbyte(0x0c); - addbyte(0x81); - addbyte(0xbd); /*MOV EBP, 8*/ - addlong(8); - addbyte(0x28); /*SUB DL, CL*/ - addbyte(0xca); - addbyte(0xd3); /*SHL EBP, CL*/ - addbyte(0xe5); - addbyte(0x8b); /*MOV EAX, state->tex_s[EDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_s)); - addbyte(0x8b); /*MOV EBX, state->tex_t[EDI]*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tex_t)); - if (params->tLOD[tmu] & LOD_TMIRROR_S) - { - addbyte(0xa9); /*TEST EAX, 0x1000*/ - addlong(0x1000); - addbyte(0x74); /*JZ +*/ - addbyte(2); - addbyte(0xf7); /*NOT EAX*/ - addbyte(0xd0); - } - if (params->tLOD[tmu] & LOD_TMIRROR_T) - { - addbyte(0xf7); /*TEST EBX, 0x1000*/ - addbyte(0xc3); - addlong(0x1000); - addbyte(0x74); /*JZ +*/ - addbyte(2); - addbyte(0xf7); /*NOT EBX*/ - addbyte(0xd3); - } - addbyte(0x29); /*SUB EAX, EBP*/ - addbyte(0xe8); - addbyte(0x29); /*SUB EBX, EBP*/ - addbyte(0xeb); - addbyte(0xd3); /*SAR EAX, CL*/ - addbyte(0xf8); - addbyte(0xd3); /*SAR EBX, CL*/ - addbyte(0xfb); - addbyte(0x89); /*MOV EBP, EAX*/ - addbyte(0xc5); - addbyte(0x89); /*MOV ECX, EBX*/ - addbyte(0xd9); - addbyte(0x83); /*AND EBP, 0xf*/ - addbyte(0xe5); - addbyte(0xf); - addbyte(0xc1); /*SHL ECX, 4*/ - addbyte(0xe1); - addbyte(4); - addbyte(0xc1); /*SAR EAX, 4*/ - addbyte(0xf8); - addbyte(4); - addbyte(0x81); /*AND ECX, 0xf0*/ - addbyte(0xe1); - addlong(0xf0); - addbyte(0xc1); /*SAR EBX, 4*/ - addbyte(0xfb); - addbyte(4); - addbyte(0x09); /*OR EBP, ECX*/ - addbyte(0xcd); - addbyte(0x8b); /*MOV ECX, state->lod[EDI]*/ - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, lod)); - addbyte(0xc1); /*SHL EBP, 5*/ - addbyte(0xe5); - addbyte(5); - /*EAX = S, EBX = T, ECX = LOD, EDX = tex_shift, ESI=params, EDI=state, EBP = bilinear shift*/ - addbyte(0x8d); /*LEA ESI, [ESI+ECX*4]*/ - addbyte(0x34); - addbyte(0x8e); - addbyte(0x89); /*MOV ebp_store, EBP*/ - addbyte(0xaf); - addlong(offsetof(voodoo_state_t, ebp_store)); - addbyte(0x8b); /*MOV EBP, state->tex[EDI+ECX*4]*/ - addbyte(0xac); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, tex[tmu])); - addbyte(0x88); /*MOV CL, DL*/ - addbyte(0xd1); - addbyte(0x89); /*MOV EDX, EBX*/ - addbyte(0xda); - if (!state->clamp_s[tmu]) - { - addbyte(0x23); /*AND EAX, params->tex_w_mask[ESI]*/ - addbyte(0x86); - addlong(offsetof(voodoo_params_t, tex_w_mask[tmu])); - } - addbyte(0x83); /*ADD EDX, 1*/ - addbyte(0xc2); - addbyte(1); - if (state->clamp_t[tmu]) - { - addbyte(0x0f); /*CMOVS EDX, zero*/ - addbyte(0x48); - addbyte(0x15); - addlong((uint32_t)&zero); - addbyte(0x3b); /*CMP EDX, params->tex_h_mask[ESI]*/ - addbyte(0x96); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - addbyte(0x0f); /*CMOVA EDX, params->tex_h_mask[ESI]*/ - addbyte(0x47); - addbyte(0x96); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - addbyte(0x85); /*TEST EBX,EBX*/ - addbyte(0xdb); - addbyte(0x0f); /*CMOVS EBX, zero*/ - addbyte(0x48); - addbyte(0x1d); - addlong((uint32_t)&zero); - addbyte(0x3b); /*CMP EBX, params->tex_h_mask[ESI]*/ - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - addbyte(0x0f); /*CMOVA EBX, params->tex_h_mask[ESI]*/ - addbyte(0x47); - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - } - else - { - addbyte(0x23); /*AND EDX, params->tex_h_mask[ESI]*/ - addbyte(0x96); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - addbyte(0x23); /*AND EBX, params->tex_h_mask[ESI]*/ - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - } - /*EAX = S, EBX = T0, EDX = T1*/ - addbyte(0xd3); /*SHL EBX, CL*/ - addbyte(0xe3); - addbyte(0xd3); /*SHL EDX, CL*/ - addbyte(0xe2); - addbyte(0x8d); /*LEA EBX,[EBP+EBX*2]*/ - addbyte(0x5c); - addbyte(0x9d); - addbyte(0); - addbyte(0x8d); /*LEA EDX,[EBP+EDX*2]*/ - addbyte(0x54); - addbyte(0x95); - addbyte(0); - if (state->clamp_s[tmu]) - { - addbyte(0x8b); /*MOV EBP, params->tex_w_mask[ESI]*/ - addbyte(0xae); - addlong(offsetof(voodoo_params_t, tex_w_mask[tmu])); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x8b); /*MOV ESI, ebp_store*/ - addbyte(0xb7); - addlong(offsetof(voodoo_state_t, ebp_store)); - addbyte(0x0f); /*CMOVS EAX, zero*/ - addbyte(0x48); - addbyte(0x05); - addlong((uint32_t)&zero); - addbyte(0x78); /*JS + - clamp on 0*/ - addbyte(2+3+2+ 5+5+2); - addbyte(0x3b); /*CMP EAX, EBP*/ - addbyte(0xc5); - addbyte(0x0f); /*CMOVAE EAX, EBP*/ - addbyte(0x43); - addbyte(0xc5); - addbyte(0x73); /*JAE + - clamp on +*/ - addbyte(5+5+2); - } - else - { - addbyte(0x3b); /*CMP EAX, params->tex_w_mask[ESI] - is S at texture edge (ie will wrap/clamp)?*/ - addbyte(0x86); - addlong(offsetof(voodoo_params_t, tex_w_mask[tmu])); - addbyte(0x8b); /*MOV ESI, ebp_store*/ - addbyte(0xb7); - addlong(offsetof(voodoo_state_t, ebp_store)); - addbyte(0x74); /*JE +*/ - addbyte(5+5+2); - } - - addbyte(0xf3); /*MOVQ XMM0, [EBX+EAX*4]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x04); - addbyte(0x83); - addbyte(0xf3); /*MOVQ XMM1, [EDX+EAX*4]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x0c); - addbyte(0x82); - - if (state->clamp_s[tmu]) - { - addbyte(0xeb); /*JMP +*/ - addbyte(5+5+4+4); - - /*S clamped - the two S coordinates are the same*/ - addbyte(0x66); /*MOVD XMM0, [EBX+EAX*4]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x04); - addbyte(0x83); - addbyte(0x66); /*MOVD XMM1, [EDX+EAX*4]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x0c); - addbyte(0x82); - addbyte(0x66); /*PUNPCKLDQ XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0); - addbyte(0x66); /*PUNPCKLDQ XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc9); - } - else - { - addbyte(0xeb); /*JMP +*/ - addbyte(5+5+5+5+6+6); - - /*S wrapped - the two S coordinates are not contiguous*/ - addbyte(0x66); /*MOVD XMM0, [EBX+EAX*4]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x04); - addbyte(0x83); - addbyte(0x66); /*MOVD XMM1, [EDX+EAX*4]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x0c); - addbyte(0x82); - addbyte(0x66); /*PINSRW XMM0, [EBX], 2*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x03); - addbyte(0x02); - addbyte(0x66); /*PINSRW XMM1, [EDX], 2*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x0a); - addbyte(0x02); - addbyte(0x66); /*PINSRW XMM0, 2[EBX], 3*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x43); - addbyte(0x02); - addbyte(0x03); - addbyte(0x66); /*PINSRW XMM1, 2[EDX], 3*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x4a); - addbyte(0x02); - addbyte(0x03); - } - - addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc2); - addbyte(0x66); /*PUNPCKLBW XMM1, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xca); - - addbyte(0x81); /*ADD ESI, bilinear_lookup*/ - addbyte(0xc6); - addlong((uint32_t)bilinear_lookup); - - addbyte(0x66); /*PMULLW XMM0, bilinear_lookup[ESI]*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x06); - addbyte(0x66); /*PMULLW XMM1, bilinear_lookup[ESI]+0x10*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x4e); - addbyte(0x10); - addbyte(0x66); /*PADDW XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc0 | 1 | (0 << 3)); - addbyte(0x66); /*MOV XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0xc0 | 0 | (1 << 3)); - addbyte(0x66); /*PSRLDQ XMM0, 64*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xd8); - addbyte(8); - addbyte(0x66); /*PADDW XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc0 | 1 | (0 << 3)); - addbyte(0x66); /*PSRLW XMM0, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd0 | 0); - addbyte(8); - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); - - addbyte(0x8b); /*MOV ESI, [ESP+8]*/ - addbyte(0x74); - addbyte(0x24); - addbyte(8+16); /*CHECK!*/ - - addbyte(0x66); /*MOV EAX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc0); - } - else - { - addbyte(0x8b); /*MOV ECX, state->tex_lod[tmu]*/ - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, tex_lod[tmu])); - addbyte(0xb2); /*MOV DL, 8*/ - addbyte(8); - addbyte(0x8b); /*MOV ECX, [ECX+EAX*4]*/ - addbyte(0x0c); - addbyte(0x81); - addbyte(0x8b); /*MOV EBP, state->tex[EDI+ECX*4]*/ - addbyte(0xac); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, tex[tmu])); - addbyte(0x28); /*SUB DL, CL*/ - addbyte(0xca); - addbyte(0x80); /*ADD CL, 4*/ - addbyte(0xc1); - addbyte(4); - addbyte(0x8b); /*MOV EAX, state->tex_s[EDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_s)); - addbyte(0x8b); /*MOV EBX, state->tex_t[EDI]*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tex_t)); - if (params->tLOD[tmu] & LOD_TMIRROR_S) - { - addbyte(0xa9); /*TEST EAX, 0x1000*/ - addlong(0x1000); - addbyte(0x74); /*JZ +*/ - addbyte(2); - addbyte(0xf7); /*NOT EAX*/ - addbyte(0xd0); - } - if (params->tLOD[tmu] & LOD_TMIRROR_T) - { - addbyte(0xf7); /*TEST EBX, 0x1000*/ - addbyte(0xc3); - addlong(0x1000); - addbyte(0x74); /*JZ +*/ - addbyte(2); - addbyte(0xf7); /*NOT EBX*/ - addbyte(0xd3); - } - addbyte(0xd3); /*SHR EAX, CL*/ - addbyte(0xe8); - addbyte(0xd3); /*SHR EBX, CL*/ - addbyte(0xeb); - if (state->clamp_s[tmu]) - { - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*CMOVS EAX, zero*/ - addbyte(0x48); - addbyte(0x05); - addlong((uint32_t)&zero); - addbyte(0x3b); /*CMP EAX, params->tex_w_mask[ESI+ECX*4]*/ - addbyte(0x84); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, tex_w_mask[tmu]) - 0x10); - addbyte(0x0f); /*CMOVAE EAX, params->tex_w_mask[ESI+ECX*4]*/ - addbyte(0x43); - addbyte(0x84); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, tex_w_mask[tmu]) - 0x10); - - } - else - { - addbyte(0x23); /*AND EAX, params->tex_w_mask-0x10[ESI+ECX*4]*/ - addbyte(0x84); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, tex_w_mask[tmu]) - 0x10); - } - if (state->clamp_t[tmu]) - { - addbyte(0x85); /*TEST EBX, EBX*/ - addbyte(0xdb); - addbyte(0x0f); /*CMOVS EBX, zero*/ - addbyte(0x48); - addbyte(0x1d); - addlong((uint32_t)&zero); - addbyte(0x3b); /*CMP EBX, params->tex_h_mask[ESI+ECX*4]*/ - addbyte(0x9c); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu]) - 0x10); - addbyte(0x0f); /*CMOVAE EBX, params->tex_h_mask[ESI+ECX*4]*/ - addbyte(0x43); - addbyte(0x9c); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu]) - 0x10); - } - else - { - addbyte(0x23); /*AND EBX, params->tex_h_mask-0x10[ESI+ECX*4]*/ - addbyte(0x9c); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, tex_h_mask[tmu]) - 0x10); - } - addbyte(0x88); /*MOV CL, DL*/ - addbyte(0xd1); - addbyte(0xd3); /*SHL EBX, CL*/ - addbyte(0xe3); - addbyte(0x01); /*ADD EBX, EAX*/ - addbyte(0xc3); - - addbyte(0x8b); /*MOV EAX,[EBP+EBX*4]*/ - addbyte(0x44); - addbyte(0x9d); - addbyte(0); - } - } - - return block_pos; -} - -static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int depthop) -{ - int block_pos = 0; - int z_skip_pos = 0; - int a_skip_pos = 0; - int chroma_skip_pos = 0; - int depth_jump_pos = 0; - int depth_jump_pos2 = 0; - int loop_jump_pos = 0; -// xmm_01_w = (__m128i)0x0001000100010001ull; -// xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull; -// xmm_ff_b = (__m128i)0x00000000ffffffffull; - xmm_01_w = _mm_set_epi32(0, 0, 0x00010001, 0x00010001); - xmm_ff_w = _mm_set_epi32(0, 0, 0x00ff00ff, 0x00ff00ff); - xmm_ff_b = _mm_set_epi32(0, 0, 0, 0x00ffffff); - minus_254 = _mm_set_epi32(0, 0, 0xff02ff02, 0xff02ff02); -// *(uint64_t *)&const_1_48 = 0x45b0000000000000ull; -// block_pos = 0; -// voodoo_get_depth = &code_block[block_pos]; - /*W at (%esp+4) - Z at (%esp+12) - new_depth at (%esp+16)*/ -// if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depth_op == DEPTHOP_NEVER)) -// { -// addbyte(0xC3); /*RET*/ -// return; -// } - addbyte(0x55); /*PUSH EBP*/ - addbyte(0x57); /*PUSH EDI*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0x53); /*PUSH EBX*/ - - addbyte(0x8b); /*MOV EDI, [ESP+4]*/ - addbyte(0x7c); - addbyte(0x24); - addbyte(4+16); - loop_jump_pos = block_pos; - addbyte(0x8b); /*MOV ESI, [ESP+8]*/ - addbyte(0x74); - addbyte(0x24); - addbyte(8+16); - addbyte(0x66); /*PXOR XMM2, XMM2*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xd2); - - if ((params->fbzMode & FBZ_W_BUFFER) || (params->fogMode & (FOG_ENABLE|FOG_CONSTANT|FOG_Z|FOG_ALPHA)) == FOG_ENABLE) - { - addbyte(0xb8); /*MOV new_depth, 0*/ - addlong(0); - addbyte(0x66); /*TEST w+4, 0xffff*/ - addbyte(0xf7); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, w)+4); - addword(0xffff); - addbyte(0x75); /*JNZ got_depth*/ - depth_jump_pos = block_pos; - addbyte(0); -// addbyte(4+5+2+3+2+5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); - addbyte(0x8b); /*MOV EDX, w*/ - addbyte(0x97); - addlong(offsetof(voodoo_state_t, w)); - addbyte(0xb8); /*MOV new_depth, 0xf001*/ - addlong(0xf001); - addbyte(0x89); /*MOV EBX, EDX*/ - addbyte(0xd3); - addbyte(0xc1); /*SHR EDX, 16*/ - addbyte(0xea); - addbyte(16); - addbyte(0x74); /*JZ got_depth*/ - depth_jump_pos2 = block_pos; - addbyte(0); -// addbyte(5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); - addbyte(0xb9); /*MOV ECX, 19*/ - addlong(19); - addbyte(0x0f); /*BSR EAX, EDX*/ - addbyte(0xbd); - addbyte(0xc2); - addbyte(0xba); /*MOV EDX, 15*/ - addlong(15); - addbyte(0xf7); /*NOT EBX*/ - addbyte(0xd3); - addbyte(0x29); /*SUB EDX, EAX - EDX = exp*/ - addbyte(0xc2); - addbyte(0x29); /*SUB ECX, EDX*/ - addbyte(0xd1); - addbyte(0xc1); /*SHL EDX, 12*/ - addbyte(0xe2); - addbyte(12); - addbyte(0xd3); /*SHR EBX, CL*/ - addbyte(0xeb); - addbyte(0x81); /*AND EBX, 0xfff - EBX = mant*/ - addbyte(0xe3); - addlong(0xfff); - addbyte(0x8d); /*LEA EAX, 1[EDX, EBX]*/ - addbyte(0x44); - addbyte(0x13); - addbyte(1); - addbyte(0xbb); /*MOV EBX, 0xffff*/ - addlong(0xffff); - addbyte(0x39); /*CMP EAX, EBX*/ - addbyte(0xd8); - addbyte(0x0f); /*CMOVA EAX, EBX*/ - addbyte(0x47); - addbyte(0xc3); - - if (depth_jump_pos) - *(uint8_t *)&code_block[depth_jump_pos] = (block_pos - depth_jump_pos) - 1; - if (depth_jump_pos) - *(uint8_t *)&code_block[depth_jump_pos2] = (block_pos - depth_jump_pos2) - 1; - - if ((params->fogMode & (FOG_ENABLE|FOG_CONSTANT|FOG_Z|FOG_ALPHA)) == FOG_ENABLE) - { - addbyte(0x89); /*MOV state->w_depth[EDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, w_depth)); - } - } - if (!(params->fbzMode & FBZ_W_BUFFER)) - { - addbyte(0x8b); /*MOV EAX, z*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, z)); - addbyte(0xbb); /*MOV EBX, 0xffff*/ - addlong(0xffff); - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - addbyte(0xc1); /*SAR EAX, 12*/ - addbyte(0xf8); - addbyte(12); - addbyte(0x0f); /*CMOVS EAX, ECX*/ - addbyte(0x48); - addbyte(0xc1); - addbyte(0x39); /*CMP EAX, EBX*/ - addbyte(0xd8); - addbyte(0x0f); /*CMOVA EAX, EBX*/ - addbyte(0x47); - addbyte(0xc3); - } - - if (params->fbzMode & FBZ_DEPTH_BIAS) - { - addbyte(0x0f); /*MOVSX EDX, params->zaColor[ESI]*/ - addbyte(0xbf); - addbyte(0x96); - addlong(offsetof(voodoo_params_t, zaColor)); - if (params->fbzMode & FBZ_W_BUFFER) - { - addbyte(0xbb); /*MOV EBX, 0xffff*/ - addlong(0xffff); - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - addbyte(0x01); /*ADD EAX, EDX*/ - addbyte(0xd0); - addbyte(0x0f); /*CMOVS EAX, ECX*/ - addbyte(0x48); - addbyte(0xc1); - addbyte(0x39); /*CMP EAX, EBX*/ - addbyte(0xd8); - addbyte(0x0f); /*CMOVA EAX, EBX*/ - addbyte(0x47); - addbyte(0xc3); - } - - addbyte(0x89); /*MOV state->new_depth[EDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, new_depth)); - - if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop != DEPTHOP_ALWAYS) && (depthop != DEPTHOP_NEVER)) - { - addbyte(0x8b); /*MOV EBX, state->x[EDI]*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, x)); - addbyte(0x8b);/*MOV ECX, aux_mem[EDI]*/ - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, aux_mem)); - addbyte(0x0f); /*MOVZX EBX, [ECX+EBX*2]*/ - addbyte(0xb7); - addbyte(0x1c); - addbyte(0x59); - if (params->fbzMode & FBZ_DEPTH_SOURCE) - { - addbyte(0x0f); /*MOVZX EAX, zaColor[ESI]*/ - addbyte(0xb7); - addbyte(0x86); - addlong(offsetof(voodoo_params_t, zaColor)); - } - addbyte(0x39); /*CMP EAX, EBX*/ - addbyte(0xd8); - if (depthop == DEPTHOP_LESSTHAN) - { - addbyte(0x0f); /*JAE skip*/ - addbyte(0x83); - z_skip_pos = block_pos; - addlong(0); - } - else if (depthop == DEPTHOP_EQUAL) - { - addbyte(0x0f); /*JNE skip*/ - addbyte(0x85); - z_skip_pos = block_pos; - addlong(0); - } - else if (depthop == DEPTHOP_LESSTHANEQUAL) - { - addbyte(0x0f); /*JA skip*/ - addbyte(0x87); - z_skip_pos = block_pos; - addlong(0); - } - else if (depthop == DEPTHOP_GREATERTHAN) - { - addbyte(0x0f); /*JBE skip*/ - addbyte(0x86); - z_skip_pos = block_pos; - addlong(0); - } - else if (depthop == DEPTHOP_NOTEQUAL) - { - addbyte(0x0f); /*JE skip*/ - addbyte(0x84); - z_skip_pos = block_pos; - addlong(0); - } - else if (depthop == DEPTHOP_GREATERTHANEQUAL) - { - addbyte(0x0f); /*JB skip*/ - addbyte(0x82); - z_skip_pos = block_pos; - addlong(0); - } - else - fatal("Bad depth_op\n"); - } - else if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop == DEPTHOP_NEVER)) - { - addbyte(0xC3); /*RET*/ -// addbyte(0x30); /*XOR EAX, EAX*/ -// addbyte(0xc0); - } -// else -// { -// addbyte(0xb0); /*MOV AL, 1*/ -// addbyte(1); -// } - - -// voodoo_combine = &code_block[block_pos]; - /*XMM0 = colour*/ - /*XMM2 = 0 (for unpacking*/ - - /*EDI = state, ESI = params*/ - - if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || !voodoo->dual_tmus) - { - /*TMU0 only sampling local colour or only one TMU, only sample TMU0*/ - block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 0); - - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - addbyte(0xc1); /*SHR EAX, 24*/ - addbyte(0xe8); - addbyte(24); - addbyte(0x89); /*MOV state->tex_a[EDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_a)); - } - else if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH) - { - /*TMU0 in pass-through mode, only sample TMU1*/ - block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 1); - - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - addbyte(0xc1); /*SHR EAX, 24*/ - addbyte(0xe8); - addbyte(24); - addbyte(0x89); /*MOV state->tex_a[EDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_a)); - } - else - { - block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 1); - - addbyte(0x66); /*MOVD XMM3, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xd8); - if ((params->textureMode[1] & TEXTUREMODE_TRILINEAR) && tc_sub_clocal_1) - { - addbyte(0x8b); /*MOV EAX, state->lod*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod)); - if (!tc_reverse_blend_1) - { - addbyte(0xbb); /*MOV EBX, 1*/ - addlong(1); - } - else - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - addbyte(0x83); /*AND EAX, 1*/ - addbyte(0xe0); - addbyte(1); - if (!tca_reverse_blend_1) - { - addbyte(0xb9); /*MOV ECX, 1*/ - addlong(1); - } - else - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - addbyte(0x31); /*XOR EBX, EAX*/ - addbyte(0xc3); - addbyte(0x31); /*XOR ECX, EAX*/ - addbyte(0xc1); - addbyte(0xc1); /*SHL EBX, 4*/ - addbyte(0xe3); - addbyte(4); - /*EBX = tc_reverse_blend, ECX=tca_reverse_blend*/ - } - addbyte(0x66); /*PUNPCKLBW XMM3, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xda); - if (tc_sub_clocal_1) - { - switch (tc_mselect_1) - { - case TC_MSELECT_ZERO: - addbyte(0x66); /*PXOR XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xc0); - break; - case TC_MSELECT_CLOCAL: - addbyte(0xf3); /*MOVQ XMM0, XMM3*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc3); - break; - case TC_MSELECT_AOTHER: - addbyte(0x66); /*PXOR XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xc0); - break; - case TC_MSELECT_ALOCAL: - addbyte(0xf2); /*PSHUFLW XMM0, XMM3, 0xff*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc3); - addbyte(0xff); - break; - case TC_MSELECT_DETAIL: - addbyte(0xb8); /*MOV EAX, params->detail_bias[1]*/ - addlong(params->detail_bias[1]); - addbyte(0x2b); /*SUB EAX, state->lod*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod)); - addbyte(0xba); /*MOV EDX, params->detail_max[1]*/ - addlong(params->detail_max[1]); - addbyte(0xc1); /*SHL EAX, params->detail_scale[1]*/ - addbyte(0xe0); - addbyte(params->detail_scale[1]); - addbyte(0x39); /*CMP EAX, EDX*/ - addbyte(0xd0); - addbyte(0x0f); /*CMOVNL EAX, EDX*/ - addbyte(0x4d); - addbyte(0xc2); - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - addbyte(0xf2); /*PSHUFLW XMM0, XMM0, 0*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0); - addbyte(0); - break; - case TC_MSELECT_LOD_FRAC: - addbyte(0x66); /*MOVD XMM0, state->lod_frac[1]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_frac[1])); - addbyte(0xf2); /*PSHUFLW XMM0, XMM0, 0*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0); - addbyte(0); - break; - } - if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) - { - addbyte(0x66); /*PXOR XMM0, xmm_00_ff_w[EBX]*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x83); - addlong((uint32_t)&xmm_00_ff_w[0]); - } - else if (!tc_reverse_blend_1) - { - addbyte(0x66); /*PXOR XMM0, xmm_ff_w*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x05); - addlong((uint32_t)&xmm_ff_w); - } - addbyte(0x66); /*PADD XMM0, xmm_01_w*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x05); - addlong((uint32_t)&xmm_01_w); - addbyte(0xf3); /*MOVQ XMM1, XMM2*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xca); - addbyte(0xf3); /*MOVQ XMM5, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe8); - addbyte(0x66); /*PMULLW XMM0, XMM3*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xc3); - addbyte(0x66); /*PMULHW XMM5, XMM3*/ - addbyte(0x0f); - addbyte(0xe5); - addbyte(0xeb); - addbyte(0x66); /*PUNPCKLWD XMM0, XMM5*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xc5); - addbyte(0x66); /*PSRAD XMM0, 8*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe0); - addbyte(8); - addbyte(0x66); /*PACKSSDW XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0); - addbyte(0x66); /*PSUBW XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xc8); - if (tc_add_clocal_1) - { - addbyte(0x66); /*PADDW XMM1, XMM3*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xcb); - } - else if (tc_add_alocal_1) - { - addbyte(0xf2); /*PSHUFLW XMM0, XMM3, 0xff*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc3); - addbyte(0xff); - addbyte(0x66); /*PADDW XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc8); - } - addbyte(0xf3); /*MOVD XMM3, XMM1*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xd9); - addbyte(0x66); /*PACKUSWB XMM3, XMM3*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xdb); - if (tca_sub_clocal_1) - { - addbyte(0x66); /*MOVD EBX, XMM3*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xdb); - } - addbyte(0x66); /*PUNPCKLBW XMM3, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xda); - } - - if (tca_sub_clocal_1) - { - addbyte(0xc1); /*SHR EBX, 24*/ - addbyte(0xeb); - addbyte(24); - switch (tca_mselect_1) - { - case TCA_MSELECT_ZERO: - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - break; - case TCA_MSELECT_CLOCAL: - addbyte(0x89); /*MOV EAX, EBX*/ - addbyte(0xd8); - break; - case TCA_MSELECT_AOTHER: - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - break; - case TCA_MSELECT_ALOCAL: - addbyte(0x89); /*MOV EAX, EBX*/ - addbyte(0xd8); - break; - case TCA_MSELECT_DETAIL: - addbyte(0xb8); /*MOV EAX, params->detail_bias[1]*/ - addlong(params->detail_bias[1]); - addbyte(0x2b); /*SUB EAX, state->lod*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod)); - addbyte(0xba); /*MOV EDX, params->detail_max[1]*/ - addlong(params->detail_max[1]); - addbyte(0xc1); /*SHL EAX, params->detail_scale[1]*/ - addbyte(0xe0); - addbyte(params->detail_scale[1]); - addbyte(0x39); /*CMP EAX, EDX*/ - addbyte(0xd0); - addbyte(0x0f); /*CMOVNL EAX, EDX*/ - addbyte(0x4d); - addbyte(0xc2); - break; - case TCA_MSELECT_LOD_FRAC: - addbyte(0x8b); /*MOV EAX, state->lod_frac[1]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod_frac[1])); - break; - } - if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) - { - addbyte(0x33); /*XOR EAX, i_00_ff_w[ECX*4]*/ - addbyte(0x04); - addbyte(0x8d); - addlong((uint32_t)i_00_ff_w); - } - else if (!tc_reverse_blend_1) - { - addbyte(0x35); /*XOR EAX, 0xff*/ - addlong(0xff); - } - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(1); - addbyte(0x0f); /*IMUL EAX, EBX*/ - addbyte(0xaf); - addbyte(0xc3); - addbyte(0xb9); /*MOV ECX, 0xff*/ - addlong(0xff); - addbyte(0xf7); /*NEG EAX*/ - addbyte(0xd8); - addbyte(0xc1); /*SAR EAX, 8*/ - addbyte(0xf8); - addbyte(8); - if (tca_add_clocal_1 || tca_add_alocal_1) - { - addbyte(0x01); /*ADD EAX, EBX*/ - addbyte(0xd8); - } - addbyte(0x39); /*CMP ECX, EAX*/ - addbyte(0xc1); - addbyte(0x0f); /*CMOVA ECX, EAX*/ - addbyte(0x47); - addbyte(0xc8); - addbyte(0x66); /*PINSRW 3, XMM3, XMM0*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0xd8); - addbyte(3); - } - - block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 0); - - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - addbyte(0x66); /*MOVD XMM7, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xf8); - - if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) - { - addbyte(0x8b); /*MOV EAX, state->lod*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod)); - if (!tc_reverse_blend) - { - addbyte(0xbb); /*MOV EBX, 1*/ - addlong(1); - } - else - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - addbyte(0x83); /*AND EAX, 1*/ - addbyte(0xe0); - addbyte(1); - if (!tca_reverse_blend) - { - addbyte(0xb9); /*MOV ECX, 1*/ - addlong(1); - } - else - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - addbyte(0x31); /*XOR EBX, EAX*/ - addbyte(0xc3); - addbyte(0x31); /*XOR ECX, EAX*/ - addbyte(0xc1); - addbyte(0xc1); /*SHL EBX, 4*/ - addbyte(0xe3); - addbyte(4); - /*EBX = tc_reverse_blend, ECX=tca_reverse_blend*/ - } - - /*XMM0 = TMU0 output, XMM3 = TMU1 output*/ - - addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc2); - if (tc_zero_other) - { - addbyte(0x66); /*PXOR XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xc9); - } - else - { - addbyte(0xf3); /*MOV XMM1, XMM3*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xcb); - } - if (tc_sub_clocal) - { - addbyte(0x66); /*PSUBW XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xc8); - } - - switch (tc_mselect) - { - case TC_MSELECT_ZERO: - addbyte(0x66); /*PXOR XMM4, XMM4*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xe4); - break; - case TC_MSELECT_CLOCAL: - addbyte(0xf3); /*MOV XMM4, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe0); - break; - case TC_MSELECT_AOTHER: - addbyte(0xf2); /*PSHUFLW XMM4, XMM3, 3, 3, 3, 3*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xe3); - addbyte(0xff); - break; - case TC_MSELECT_ALOCAL: - addbyte(0xf2); /*PSHUFLW XMM4, XMM0, 3, 3, 3, 3*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xe0); - addbyte(0xff); - break; - case TC_MSELECT_DETAIL: - addbyte(0xb8); /*MOV EAX, params->detail_bias[0]*/ - addlong(params->detail_bias[0]); - addbyte(0x2b); /*SUB EAX, state->lod*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, lod)); - addbyte(0xba); /*MOV EDX, params->detail_max[0]*/ - addlong(params->detail_max[0]); - addbyte(0xc1); /*SHL EAX, params->detail_scale[0]*/ - addbyte(0xe0); - addbyte(params->detail_scale[0]); - addbyte(0x39); /*CMP EAX, EDX*/ - addbyte(0xd0); - addbyte(0x0f); /*CMOVNL EAX, EDX*/ - addbyte(0x4d); - addbyte(0xc2); - addbyte(0x66); /*MOVD XMM4, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xe0); - addbyte(0xf2); /*PSHUFLW XMM4, XMM4, 0*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xe4); - addbyte(0); - break; - case TC_MSELECT_LOD_FRAC: - addbyte(0x66); /*MOVD XMM0, state->lod_frac[0]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xa7); - addlong(offsetof(voodoo_state_t, lod_frac[0])); - addbyte(0xf2); /*PSHUFLW XMM0, XMM0, 0*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xe4); - addbyte(0); - break; - } - if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) - { - addbyte(0x66); /*PXOR XMM4, xmm_00_ff_w[EBX]*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xa3); - addlong((uint32_t)&xmm_00_ff_w[0]); - } - else if (!tc_reverse_blend) - { - addbyte(0x66); /*PXOR XMM4, FF*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x25); - addlong((uint32_t)&xmm_ff_w); - } - addbyte(0x66); /*PADDW XMM4, 1*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x25); - addlong((uint32_t)&xmm_01_w); - addbyte(0xf3); /*MOVQ XMM5, XMM1*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe9); - addbyte(0x66); /*PMULLW XMM1, XMM4*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xcc); - - if (tca_sub_clocal) - { - addbyte(0x66); /*MOV EBX, XMM7*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xfb); - } - - addbyte(0x66); /*PMULHW XMM5, XMM4*/ - addbyte(0x0f); - addbyte(0xe5); - addbyte(0xec); - addbyte(0x66); /*PUNPCKLWD XMM1, XMM5*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xcd); - addbyte(0x66); /*PSRAD XMM1, 8*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe1); - addbyte(8); - addbyte(0x66); /*PACKSSDW XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc9); - - if (tca_sub_clocal) - { - addbyte(0xc1); /*SHR EBX, 24*/ - addbyte(0xeb); - addbyte(24); - } - - if (tc_add_clocal) - { - addbyte(0x66); /*PADDW XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc8); - } - else if (tc_add_alocal) - { - addbyte(0xf2); /*PSHUFLW XMM4, XMM0, 3, 3, 3, 3*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xe0); - addbyte(0xff); - addbyte(0x66); /*PADDW XMM1, XMM4*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xcc); - } - - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); - addbyte(0x66); /*PACKUSWB XMM3, XMM3*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xdb); - addbyte(0x66); /*PACKUSWB XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc9); - if (tc_invert_output) - { - addbyte(0x66); /*PXOR XMM1, FF*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x0d); - addlong((uint32_t)&xmm_ff_b); - } - - if (tca_zero_other) - { - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - } - else - { - addbyte(0x66); /*MOV EAX, XMM3*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xd8); - addbyte(0xc1); /*SHR EAX, 24*/ - addbyte(0xe8); - addbyte(24); - } - if (tca_sub_clocal) - { - addbyte(0x29); /*SUB EAX, EBX*/ - addbyte(0xd8); - } - switch (tca_mselect) - { - case TCA_MSELECT_ZERO: - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - break; - case TCA_MSELECT_CLOCAL: - addbyte(0x66); /*MOV EBX, XMM7*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xfb); - addbyte(0xc1); /*SHR EBX, 24*/ - addbyte(0xeb); - addbyte(24); - break; - case TCA_MSELECT_AOTHER: - addbyte(0x66); /*MOV EBX, XMM3*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xdb); - addbyte(0xc1); /*SHR EBX, 24*/ - addbyte(0xeb); - addbyte(24); - break; - case TCA_MSELECT_ALOCAL: - addbyte(0x66); /*MOV EBX, XMM7*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xfb); - addbyte(0xc1); /*SHR EBX, 24*/ - addbyte(0xeb); - addbyte(24); - break; - case TCA_MSELECT_DETAIL: - addbyte(0xbb); /*MOV EBX, params->detail_bias[1]*/ - addlong(params->detail_bias[1]); - addbyte(0x2b); /*SUB EBX, state->lod*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, lod)); - addbyte(0xba); /*MOV EDX, params->detail_max[1]*/ - addlong(params->detail_max[1]); - addbyte(0xc1); /*SHL EBX, params->detail_scale[1]*/ - addbyte(0xe3); - addbyte(params->detail_scale[1]); - addbyte(0x39); /*CMP EBX, EDX*/ - addbyte(0xd3); - addbyte(0x0f); /*CMOVNL EBX, EDX*/ - addbyte(0x4d); - addbyte(0xda); - break; - case TCA_MSELECT_LOD_FRAC: - addbyte(0x8b); /*MOV EBX, state->lod_frac[0]*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, lod_frac[0])); - break; - } - if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) - { - addbyte(0x33); /*XOR EBX, i_00_ff_w[ECX*4]*/ - addbyte(0x1c); - addbyte(0x8d); - addlong((uint32_t)i_00_ff_w); - } - else if (!tca_reverse_blend) - { - addbyte(0x81); /*XOR EBX, 0xFF*/ - addbyte(0xf3); - addlong(0xff); - } - - addbyte(0x83); /*ADD EBX, 1*/ - addbyte(0xc3); - addbyte(1); - addbyte(0x0f); /*IMUL EAX, EBX*/ - addbyte(0xaf); - addbyte(0xc3); - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - addbyte(0xc1); /*SAR EAX, 8*/ - addbyte(0xf8); - addbyte(8); - if (tca_add_clocal || tca_add_alocal) - { - addbyte(0x66); /*MOV EBX, XMM7*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xfb); - addbyte(0xc1); /*SHR EBX, 24*/ - addbyte(0xeb); - addbyte(24); - addbyte(0x01); /*ADD EAX, EBX*/ - addbyte(0xd8); - } - addbyte(0x0f); /*CMOVS EAX, EDX*/ - addbyte(0x48); - addbyte(0xc2); - addbyte(0xba); /*MOV EDX, 0xff*/ - addlong(0xff); - addbyte(0x3d); /*CMP EAX, 0xff*/ - addlong(0xff); - addbyte(0x0f); /*CMOVA EAX, EDX*/ - addbyte(0x47); - addbyte(0xc2); - if (tca_invert_output) - { - addbyte(0x35); /*XOR EAX, 0xff*/ - addlong(0xff); - } - - addbyte(0x89); /*MOV state->tex_a[EDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_a)); - - addbyte(0xf3); /*MOVQ XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc1); - } - if (cc_mselect == CC_MSELECT_TEXRGB) - { - addbyte(0xf3); /*MOVD XMM4, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe0); - } - - if ((params->fbzMode & FBZ_CHROMAKEY)) - { - addbyte(0x66); /*MOVD EAX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc0); - addbyte(0x8b); /*MOV EBX, params->chromaKey[ESI]*/ - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, chromaKey)); - addbyte(0x31); /*XOR EBX, EAX*/ - addbyte(0xc3); - addbyte(0x81); /*AND EBX, 0xffffff*/ - addbyte(0xe3); - addlong(0xffffff); - addbyte(0x0f); /*JE skip*/ - addbyte(0x84); - chroma_skip_pos = block_pos; - addlong(0); - } - - if (voodoo->trexInit1[0] & (1 << 18)) - { - addbyte(0xb8); /*MOV EAX, tmuConfig*/ - addlong(voodoo->tmuConfig); - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - } - - if ((params->alphaMode & ((1 << 0) | (1 << 4))) || (!(cc_mselect == 0 && cc_reverse_blend == 0) && (cc_mselect == CC_MSELECT_AOTHER || cc_mselect == CC_MSELECT_ALOCAL))) - { - /*EBX = a_other*/ - switch (a_sel) - { - case A_SEL_ITER_A: - addbyte(0x8b); /*MOV EBX, state->ia*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, ia)); - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xba); /*MOV EDX, 0xff*/ - addlong(0xff); - addbyte(0xc1); /*SAR EBX, 12*/ - addbyte(0xfb); - addbyte(12); - addbyte(0x0f); /*CMOVS EBX, EAX*/ - addbyte(0x48); - addbyte(0xd8); - addbyte(0x39); /*CMP EBX, EDX*/ - addbyte(0xd3); - addbyte(0x0f); /*CMOVA EBX, EDX*/ - addbyte(0x47); - addbyte(0xda); - break; - case A_SEL_TEX: - addbyte(0x8b); /*MOV EBX, state->tex_a*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tex_a)); - break; - case A_SEL_COLOR1: - addbyte(0x0f); /*MOVZX EBX, params->color1+3*/ - addbyte(0xb6); - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, color1)+3); - break; - default: - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - break; - } - /*ECX = a_local*/ - switch (cca_localselect) - { - case CCA_LOCALSELECT_ITER_A: - if (a_sel == A_SEL_ITER_A) - { - addbyte(0x89); /*MOV ECX, EBX*/ - addbyte(0xd9); - } - else - { - addbyte(0x8b); /*MOV ECX, state->ia*/ - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, ia)); - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xba); /*MOV EDX, 0xff*/ - addlong(0xff); - addbyte(0xc1);/*SAR ECX, 12*/ - addbyte(0xf9); - addbyte(12); - addbyte(0x0f); /*CMOVS ECX, EAX*/ - addbyte(0x48); - addbyte(0xc8); - addbyte(0x39); /*CMP ECX, EDX*/ - addbyte(0xd1); - addbyte(0x0f); /*CMOVA ECX, EDX*/ - addbyte(0x47); - addbyte(0xca); - } - break; - case CCA_LOCALSELECT_COLOR0: - addbyte(0x0f); /*MOVZX ECX, params->color0+3*/ - addbyte(0xb6); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, color0)+3); - break; - case CCA_LOCALSELECT_ITER_Z: - addbyte(0x8b); /*MOV ECX, state->z*/ - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, z)); - if (a_sel != A_SEL_ITER_A) - { - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xba); /*MOV EDX, 0xff*/ - addlong(0xff); - } - addbyte(0xc1);/*SAR ECX, 20*/ - addbyte(0xf9); - addbyte(20); - addbyte(0x0f); /*CMOVS ECX, EAX*/ - addbyte(0x48); - addbyte(0xc8); - addbyte(0x39); /*CMP ECX, EDX*/ - addbyte(0xd1); - addbyte(0x0f); /*CMOVA ECX, EDX*/ - addbyte(0x47); - addbyte(0xca); - break; - - default: - addbyte(0xb9); /*MOV ECX, 0xff*/ - addlong(0xff); - break; - } - - if (cca_zero_other) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x89); /*MOV EDX, EBX*/ - addbyte(0xda); - } - - if (cca_sub_clocal) - { - addbyte(0x29); /*SUB EDX, ECX*/ - addbyte(0xca); - } - } - - if (cc_sub_clocal || cc_mselect == 1 || cc_add == 1) - { - /*XMM1 = local*/ - if (!cc_localselect_override) - { - if (cc_localselect) - { - addbyte(0x66); /*MOVD XMM1, params->color0*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, color0)); - } - else - { - addbyte(0xf3); /*MOVDQU XMM1, ib*/ /* ir, ig and ib must be in same dqword!*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, ib)); - addbyte(0x66); /*PSRAD XMM1, 12*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe1); - addbyte(12); - addbyte(0x66); /*PACKSSDW XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc9); - addbyte(0x66); /*PACKUSWB XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc9); - } - } - else - { - addbyte(0xf6); /*TEST state->tex_a, 0x80*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_a)); - addbyte(0x80); - addbyte(0x74);/*JZ !cc_localselect*/ - addbyte(8+2); - addbyte(0x66); /*MOVD XMM1, params->color0*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, color0)); - addbyte(0xeb); /*JMP +*/ - addbyte(8+5+4+4); - /*!cc_localselect:*/ - addbyte(0xf3); /*MOVDQU XMM1, ib*/ /* ir, ig and ib must be in same dqword!*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, ib)); - addbyte(0x66); /*PSRAD XMM1, 12*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe1); - addbyte(12); - addbyte(0x66); /*PACKSSDW XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc9); - addbyte(0x66); /*PACKUSWB XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc9); - } - addbyte(0x66); /*PUNPCKLBW XMM1, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xca); - } - if (!cc_zero_other) - { - if (_rgb_sel == CC_LOCALSELECT_ITER_RGB) - { - addbyte(0xf3); /*MOVDQU XMM0, ib*/ /* ir, ig and ib must be in same dqword!*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, ib)); - addbyte(0x66); /*PSRAD XMM0, 12*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe0); - addbyte(12); - addbyte(0x66); /*PACKSSDW XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0); - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); - } - else if (_rgb_sel == CC_LOCALSELECT_TEX) - { -#if 0 - addbyte(0xf3); /*MOVDQU XMM0, state->tex_b*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_b)); - addbyte(0x66); /*PACKSSDW XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0); - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); -#endif - } - else if (_rgb_sel == CC_LOCALSELECT_COLOR1) - { - addbyte(0x66); /*MOVD XMM0, params->color1*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x86); - addlong(offsetof(voodoo_params_t, color1)); - } - else - { - /*MOVD XMM0, src_r*/ - } - addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc2); - if (cc_sub_clocal) - { - addbyte(0x66); /*PSUBW XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xc1); - } - } - else - { - addbyte(0x66); /*PXOR XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xc0); - if (cc_sub_clocal) - { - addbyte(0x66); /*PSUBW XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xc1); - } - } - - if (params->alphaMode & ((1 << 0) | (1 << 4))) - { - if (!(cca_mselect == 0 && cca_reverse_blend == 0)) - { - switch (cca_mselect) - { - case CCA_MSELECT_ALOCAL: - addbyte(0x89); /*MOV EAX, ECX*/ - addbyte(0xc8); - break; - case CCA_MSELECT_AOTHER: - addbyte(0x89); /*MOV EAX, EBX*/ - addbyte(0xd8); - break; - case CCA_MSELECT_ALOCAL2: - addbyte(0x89); /*MOV EAX, ECX*/ - addbyte(0xc8); - break; - case CCA_MSELECT_TEX: - addbyte(0x0f); /*MOVZX EAX, state->tex_a*/ - addbyte(0xb6); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, tex_a)); - break; - - case CCA_MSELECT_ZERO: - default: - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - break; - } - if (!cca_reverse_blend) - { - addbyte(0x35); /*XOR EAX, 0xff*/ - addlong(0xff); - } - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(1); - addbyte(0x0f); /*IMUL EDX, EAX*/ - addbyte(0xaf); - addbyte(0xd0); - addbyte(0xc1); /*SHR EDX, 8*/ - addbyte(0xea); - addbyte(8); - } - } - - if ((params->alphaMode & ((1 << 0) | (1 << 4)))) - { - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - } - - if (!(cc_mselect == 0 && cc_reverse_blend == 0) && cc_mselect == CC_MSELECT_AOTHER) - { - /*Copy a_other to XMM3 before it gets modified*/ - addbyte(0x66); /*MOVD XMM3, EDX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xda); - addbyte(0xf2); /*PSHUFLW XMM3, XMM3, 0*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xdb); - addbyte(0x00); - } - - if (cca_add && (params->alphaMode & ((1 << 0) | (1 << 4)))) - { - addbyte(0x01); /*ADD EDX, ECX*/ - addbyte(0xca); - } - - if ((params->alphaMode & ((1 << 0) | (1 << 4)))) - { - addbyte(0x85); /*TEST EDX, EDX*/ - addbyte(0xd2); - addbyte(0x0f); /*CMOVS EDX, EAX*/ - addbyte(0x48); - addbyte(0xd0); - addbyte(0xb8); /*MOV EAX, 0xff*/ - addlong(0xff); - addbyte(0x81); /*CMP EDX, 0xff*/ - addbyte(0xfa); - addlong(0xff); - addbyte(0x0f); /*CMOVA EDX, EAX*/ - addbyte(0x47); - addbyte(0xd0); - - if (cca_invert_output) - { - addbyte(0x81); /*XOR EDX, 0xff*/ - addbyte(0xf2); - addlong(0xff); - } - } - - if (!(cc_mselect == 0 && cc_reverse_blend == 0)) - { - switch (cc_mselect) - { - case CC_MSELECT_ZERO: - addbyte(0x66); /*PXOR XMM3, XMM3*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xdb); - break; - case CC_MSELECT_CLOCAL: - addbyte(0xf3); /*MOV XMM3, XMM1*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xd9); - break; - case CC_MSELECT_ALOCAL: - addbyte(0x66); /*MOVD XMM3, ECX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xd9); - addbyte(0xf2); /*PSHUFLW XMM3, XMM3, 0*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xdb); - addbyte(0x00); - break; - case CC_MSELECT_AOTHER: - /*Handled above*/ - break; - case CC_MSELECT_TEX: - addbyte(0x66); /*PINSRW XMM3, state->tex_a, 0*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tex_a)); - addbyte(0); - addbyte(0x66); /*PINSRW XMM3, state->tex_a, 1*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tex_a)); - addbyte(1); - addbyte(0x66); /*PINSRW XMM3, state->tex_a, 2*/ - addbyte(0x0f); - addbyte(0xc4); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tex_a)); - addbyte(2); - break; - case CC_MSELECT_TEXRGB: - addbyte(0x66); /*PUNPCKLBW XMM4, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xe2); - addbyte(0xf3); /*MOVQ XMM3, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xdc); - break; - default: - addbyte(0x66); /*PXOR XMM3, XMM3*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xdb); - break; - } - addbyte(0xf3); /*MOV XMM4, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe0); - if (!cc_reverse_blend) - { - addbyte(0x66); /*PXOR XMM3, 0xff*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x1d); - addlong((uint32_t)&xmm_ff_w); - } - addbyte(0x66); /*PADDW XMM3, 1*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x1d); - addlong((uint32_t)&xmm_01_w); - addbyte(0x66); /*PMULLW XMM0, XMM3*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xc3); - addbyte(0x66); /*PMULHW XMM4, XMM3*/ - addbyte(0x0f); - addbyte(0xe5); - addbyte(0xe3); - addbyte(0x66); /*PUNPCKLWD XMM0, XMM4*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xc4); - addbyte(0x66); /*PSRLD XMM0, 8*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe0); - addbyte(8); - addbyte(0x66); /*PACKSSDW XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0); - } - - if (cc_add == 1) - { - addbyte(0x66); /*PADDW XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc1); - } - - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); - - if (cc_invert_output) - { - addbyte(0x66); /*PXOR XMM0, 0xff*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x05); - addlong((uint32_t)&xmm_ff_b); - } -//#if 0 -// addbyte(0x66); /*MOVD state->out[EDI], XMM0*/ -// addbyte(0x0f); -// addbyte(0x7e); -// addbyte(0x87); -// addlong(offsetof(voodoo_state_t, out)); - if (params->fogMode & FOG_ENABLE) - { - if (params->fogMode & FOG_CONSTANT) - { - addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, fogColor)); - addbyte(0x66); /*PADDUSB XMM0, XMM3*/ - addbyte(0x0f); - addbyte(0xdc); - addbyte(0xc3); -/* src_r += params->fogColor.r; - src_g += params->fogColor.g; - src_b += params->fogColor.b; */ - } - else - { - /*int fog_r, fog_g, fog_b, fog_a; */ - - addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc2); - - if (!(params->fogMode & FOG_ADD)) - { - addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x9e); - addlong(offsetof(voodoo_params_t, fogColor)); - addbyte(0x66); /*PUNPCKLBW XMM3, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xda); - } - else - { - addbyte(0x66); /*PXOR XMM3, XMM3*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xdb); - } - - if (!(params->fogMode & FOG_MULT)) - { - addbyte(0x66); /*PSUBW XMM3, XMM0*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xd8); - } - - /*Divide by 2 to prevent overflow on multiply*/ - addbyte(0x66); /*PSRAW XMM3, 1*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xe3); - addbyte(1); - - switch (params->fogMode & (FOG_Z|FOG_ALPHA)) - { - case 0: - addbyte(0x8b); /*MOV EBX, state->w_depth[EDI]*/ - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, w_depth)); - addbyte(0x89); /*MOV EAX, EBX*/ - addbyte(0xd8); - addbyte(0xc1); /*SHR EBX, 10*/ - addbyte(0xeb); - addbyte(10); - addbyte(0xc1); /*SHR EAX, 2*/ - addbyte(0xe8); - addbyte(2); - addbyte(0x83); /*AND EBX, 0x3f*/ - addbyte(0xe3); - addbyte(0x3f); - addbyte(0x25); /*AND EAX, 0xff*/ - addlong(0xff); - addbyte(0xf6); /*MUL params->fogTable+1[ESI+EBX*2]*/ - addbyte(0xa4); - addbyte(0x5e); - addlong(offsetof(voodoo_params_t, fogTable)+1); - addbyte(0x0f); /*MOVZX EBX, params->fogTable[ESI+EBX*2]*/ - addbyte(0xb6); - addbyte(0x9c); - addbyte(0x5e); - addlong(offsetof(voodoo_params_t, fogTable)); - addbyte(0xc1); /*SHR EAX, 10*/ - addbyte(0xe8); - addbyte(10); - addbyte(0x01); /*ADD EAX, EBX*/ - addbyte(0xd8); - -/* int fog_idx = (w_depth >> 10) & 0x3f; - - fog_a = params->fogTable[fog_idx].fog; - fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10;*/ - break; - - case FOG_Z: - addbyte(0x8b); /*MOV EAX, state->z[EDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, z)); - addbyte(0xc1); /*SHR EAX, 12*/ - addbyte(0xe8); - addbyte(12); - addbyte(0x25); /*AND EAX, 0xff*/ - addlong(0xff); -// fog_a = (z >> 20) & 0xff; - break; - - case FOG_ALPHA: - addbyte(0x8b); /*MOV EAX, state->ia[EDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, ia)); - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - addbyte(0xc1); /*SAR EAX, 12*/ - addbyte(0xf8); - addbyte(12); - addbyte(0x0f); /*CMOVS EAX, EBX*/ - addbyte(0x48); - addbyte(0xc3); - addbyte(0xbb); /*MOV EBX, 0xff*/ - addlong(0xff); - addbyte(0x3d); /*CMP EAX, 0xff*/ - addlong(0xff); - addbyte(0x0f); /*CMOVAE EAX, EBX*/ - addbyte(0x43); - addbyte(0xc3); -// fog_a = CLAMP(ia >> 12); - break; - - case FOG_W: - addbyte(0x8b); /*MOV EAX, state->w[EDI]+4*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, w)+4); - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - addbyte(0x09); /*OR EAX, EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*CMOVS EAX, EBX*/ - addbyte(0x48); - addbyte(0xc3); - addbyte(0xbb); /*MOV EBX, 0xff*/ - addlong(0xff); - addbyte(0x3d); /*CMP EAX, 0xff*/ - addlong(0xff); - addbyte(0x0f); /*CMOVAE EAX, EBX*/ - addbyte(0x43); - addbyte(0xc3); -// fog_a = CLAMP(w >> 32); - break; - } - addbyte(0x01); /*ADD EAX, EAX*/ - addbyte(0xc0); -// fog_a++; - - addbyte(0x66); /*PMULLW XMM3, alookup+4[EAX*8]*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x1c); - addbyte(0xc5); - addlong(((uintptr_t)alookup) + 16); - addbyte(0x66); /*PSRAW XMM3, 7*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xe3); - addbyte(7); -/* fog_r = (fog_r * fog_a) >> 8; - fog_g = (fog_g * fog_a) >> 8; - fog_b = (fog_b * fog_a) >> 8;*/ - - if (params->fogMode & FOG_MULT) - { - addbyte(0xf3); /*MOV XMM0, XMM3*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc3); - } - else - { - addbyte(0x66); /*PADDW XMM0, XMM3*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc3); -/* src_r += fog_r; - src_g += fog_g; - src_b += fog_b;*/ - } - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); - } - -/* src_r = CLAMP(src_r); - src_g = CLAMP(src_g); - src_b = CLAMP(src_b);*/ - } - - if ((params->alphaMode & 1) && (alpha_func != AFUNC_NEVER) && (alpha_func != AFUNC_ALWAYS)) - { - addbyte(0x0f); /*MOVZX ECX, params->alphaMode+3*/ - addbyte(0xb6); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, alphaMode) + 3); - addbyte(0x39); /*CMP EDX, ECX*/ - addbyte(0xca); - - switch (alpha_func) - { - case AFUNC_LESSTHAN: - addbyte(0x0f); /*JAE skip*/ - addbyte(0x83); - a_skip_pos = block_pos; - addlong(0); - break; - case AFUNC_EQUAL: - addbyte(0x0f); /*JNE skip*/ - addbyte(0x85); - a_skip_pos = block_pos; - addlong(0); - break; - case AFUNC_LESSTHANEQUAL: - addbyte(0x0f); /*JA skip*/ - addbyte(0x87); - a_skip_pos = block_pos; - addlong(0); - break; - case AFUNC_GREATERTHAN: - addbyte(0x0f); /*JBE skip*/ - addbyte(0x86); - a_skip_pos = block_pos; - addlong(0); - break; - case AFUNC_NOTEQUAL: - addbyte(0x0f); /*JE skip*/ - addbyte(0x84); - a_skip_pos = block_pos; - addlong(0); - break; - case AFUNC_GREATERTHANEQUAL: - addbyte(0x0f); /*JB skip*/ - addbyte(0x82); - a_skip_pos = block_pos; - addlong(0); - break; - } - } - else if ((params->alphaMode & 1) && (alpha_func == AFUNC_NEVER)) - { - addbyte(0xC3); /*RET*/ - } - - if (params->alphaMode & (1 << 4)) - { - addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, x)); - addbyte(0x8b); /*MOV EBP, fb_mem*/ - addbyte(0xaf); - addlong(offsetof(voodoo_state_t, fb_mem)); - addbyte(0x01); /*ADD EDX, EDX*/ - addbyte(0xd2); - addbyte(0x0f); /*MOVZX EAX, [EBP+EAX*2]*/ - addbyte(0xb7); - addbyte(0x44); - addbyte(0x45); - addbyte(0); - addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc2); - addbyte(0x66); /*MOVD XMM4, rgb565[EAX*4]*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x24); - addbyte(0x85); - addlong((uint32_t)rgb565); - addbyte(0x66); /*PUNPCKLBW XMM4, XMM2*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xe2); - addbyte(0xf3); /*MOV XMM6, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xf4); - - switch (dest_afunc) - { - case AFUNC_AZERO: - addbyte(0x66); /*PXOR XMM4, XMM4*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xe4); - break; - case AFUNC_ASRC_ALPHA: - addbyte(0x66); /*PMULLW XMM4, alookup[EDX*8]*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x24); - addbyte(0xd5); - addlong((uint32_t)alookup); - addbyte(0xf3); /*MOVQ XMM5, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x25); - addlong((uint32_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM4, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xe5); - addbyte(0x66); /*PSRLW XMM4, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd4); - addbyte(8); - break; - case AFUNC_A_COLOR: - addbyte(0x66); /*PMULLW XMM4, XMM0*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xe0); - addbyte(0xf3); /*MOVQ XMM5, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x25); - addlong((uint32_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM4, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xe5); - addbyte(0x66); /*PSRLW XMM4, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd4); - addbyte(8); - break; - case AFUNC_ADST_ALPHA: - break; - case AFUNC_AONE: - break; - case AFUNC_AOMSRC_ALPHA: - addbyte(0x66); /*PMULLW XMM4, aminuslookup[EDX*8]*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x24); - addbyte(0xd5); - addlong((uint32_t)aminuslookup); - addbyte(0xf3); /*MOVQ XMM5, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x25); - addlong((uint32_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM4, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xe5); - addbyte(0x66); /*PSRLW XMM4, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd4); - addbyte(8); - break; - case AFUNC_AOM_COLOR: - addbyte(0xf3); /*MOVQ XMM5, xmm_ff_w*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x2d); - addlong((uint32_t)&xmm_ff_w); - addbyte(0x66); /*PSUBW XMM5, XMM0*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xe8); - addbyte(0x66); /*PMULLW XMM4, XMM5*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xe5); - addbyte(0xf3); /*MOVQ XMM5, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x25); - addlong((uint32_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM4, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xe5); - addbyte(0x66); /*PSRLW XMM4, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd4); - addbyte(8); - break; - case AFUNC_AOMDST_ALPHA: - addbyte(0x66); /*PXOR XMM4, XMM4*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xe4); - break; - case AFUNC_ASATURATE: - addbyte(0x66); /*PMULLW XMM4, minus_254*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x25); - addlong((uint32_t)&minus_254); - addbyte(0xf3); /*MOVQ XMM5, XMM4*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x25); - addlong((uint32_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM4, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xe5); - addbyte(0x66); /*PSRLW XMM4, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd4); - addbyte(8); - } - - switch (src_afunc) - { - case AFUNC_AZERO: - addbyte(0x66); /*PXOR XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xc0); - break; - case AFUNC_ASRC_ALPHA: - addbyte(0x66); /*PMULLW XMM0, alookup[EDX*8]*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x04); - addbyte(0xd5); - addlong((uint32_t)alookup); - addbyte(0xf3); /*MOVQ XMM5, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe8); - addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x05); - addlong((uint32_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM0, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc5); - addbyte(0x66); /*PSRLW XMM0, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd0); - addbyte(8); - break; - case AFUNC_A_COLOR: - addbyte(0x66); /*PMULLW XMM0, XMM6*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xc6); - addbyte(0xf3); /*MOVQ XMM5, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe8); - addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x05); - addlong((uint32_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM0, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc5); - addbyte(0x66); /*PSRLW XMM0, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd0); - addbyte(8); - break; - case AFUNC_ADST_ALPHA: - break; - case AFUNC_AONE: - break; - case AFUNC_AOMSRC_ALPHA: - addbyte(0x66); /*PMULLW XMM0, aminuslookup[EDX*8]*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0x04); - addbyte(0xd5); - addlong((uint32_t)aminuslookup); - addbyte(0xf3); /*MOVQ XMM5, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe8); - addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x05); - addlong((uint32_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM0, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc5); - addbyte(0x66); /*PSRLW XMM0, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd0); - addbyte(8); - break; - case AFUNC_AOM_COLOR: - addbyte(0xf3); /*MOVQ XMM5, xmm_ff_w*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x2d); - addlong((uint32_t)&xmm_ff_w); - addbyte(0x66); /*PSUBW XMM5, XMM6*/ - addbyte(0x0f); - addbyte(0xf9); - addbyte(0xee); - addbyte(0x66); /*PMULLW XMM0, XMM5*/ - addbyte(0x0f); - addbyte(0xd5); - addbyte(0xc5); - addbyte(0xf3); /*MOVQ XMM5, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xe8); - addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0x05); - addlong((uint32_t)alookup + 16); - addbyte(0x66); /*PSRLW XMM5, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd5); - addbyte(8); - addbyte(0x66); /*PADDW XMM0, XMM5*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc5); - addbyte(0x66); /*PSRLW XMM0, 8*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xd0); - addbyte(8); - break; - case AFUNC_AOMDST_ALPHA: - addbyte(0x66); /*PXOR XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xc0); - break; - case AFUNC_ACOLORBEFOREFOG: - break; - } - - addbyte(0x66); /*PADDW XMM0, XMM4*/ - addbyte(0x0f); - addbyte(0xfd); - addbyte(0xc4); - - addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0); - } -//#endif - -// addbyte(0x8b); /*MOV EDX, x (ESP+12)*/ -// addbyte(0x54); -// addbyte(0x24); -// addbyte(12); - - - addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ - addbyte(0x97); - addlong(offsetof(voodoo_state_t, x)); - - addbyte(0x66); /*MOV EAX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc0); - - if (params->fbzMode & FBZ_RGB_WMASK) - { -// addbyte(0x89); /*MOV state->rgb_out[EDI], EAX*/ -// addbyte(0x87); -// addlong(offsetof(voodoo_state_t, rgb_out)); - - if (dither) - { - addbyte(0x8b); /*MOV ESI, real_y (ESP+16)*/ - addbyte(0x74); - addbyte(0x24); - addbyte(16+16); - addbyte(0x0f); /*MOVZX EBX, AH*/ /*G*/ - addbyte(0xb6); - addbyte(0xdc); - if (dither2x2) - { - addbyte(0x83); /*AND EDX, 1*/ - addbyte(0xe2); - addbyte(1); - addbyte(0x83); /*AND ESI, 1*/ - addbyte(0xe6); - addbyte(1); - addbyte(0xc1); /*SHL EBX, 2*/ - addbyte(0xe3); - addbyte(2); - } - else - { - addbyte(0x83); /*AND EDX, 3*/ - addbyte(0xe2); - addbyte(3); - addbyte(0x83); /*AND ESI, 3*/ - addbyte(0xe6); - addbyte(3); - addbyte(0xc1); /*SHL EBX, 4*/ - addbyte(0xe3); - addbyte(4); - } - addbyte(0x0f); /*MOVZX ECX, AL*/ /*R*/ - addbyte(0xb6); - addbyte(0xc8); - if (dither2x2) - { - addbyte(0xc1); /*SHR EAX, 14*/ - addbyte(0xe8); - addbyte(14); - addbyte(0x8d); /*LEA ESI, EDX+ESI*2*/ - addbyte(0x34); - addbyte(0x72); - } - else - { - addbyte(0xc1); /*SHR EAX, 12*/ - addbyte(0xe8); - addbyte(12); - addbyte(0x8d); /*LEA ESI, EDX+ESI*4*/ - addbyte(0x34); - addbyte(0xb2); - } - addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ - addbyte(0x97); - addlong(offsetof(voodoo_state_t, x)); - if (dither2x2) - { - addbyte(0xc1); /*SHL ECX, 2*/ - addbyte(0xe1); - addbyte(2); - addbyte(0x25); /*AND EAX, 0x3fc*/ /*B*/ - addlong(0x3fc); - } - else - { - addbyte(0xc1); /*SHL ECX, 4*/ - addbyte(0xe1); - addbyte(4); - addbyte(0x25); /*AND EAX, 0xff0*/ /*B*/ - addlong(0xff0); - } - addbyte(0x0f); /*MOVZX EBX, dither_g[EBX+ESI]*/ - addbyte(0xb6); - addbyte(0x9c); - addbyte(0x33); - addlong(dither2x2 ? (uint32_t)dither_g2x2 : (uint32_t)dither_g); - addbyte(0x0f); /*MOVZX ECX, dither_rb[ECX+ESI]*/ - addbyte(0xb6); - addbyte(0x8c); - addbyte(0x31); - addlong(dither2x2 ? (uint32_t)dither_rb2x2 : (uint32_t)dither_rb); - addbyte(0x0f); /*MOVZX EAX, dither_rb[EAX+ESI]*/ - addbyte(0xb6); - addbyte(0x84); - addbyte(0x30); - addlong(dither2x2 ? (uint32_t)dither_rb2x2 : (uint32_t)dither_rb); - addbyte(0xc1); /*SHL EBX, 5*/ - addbyte(0xe3); - addbyte(5); - addbyte(0xc1); /*SHL EAX, 11*/ - addbyte(0xe0); - addbyte(11); - addbyte(0x09); /*OR EAX, EBX*/ - addbyte(0xd8); - addbyte(0x09); /*OR EAX, ECX*/ - addbyte(0xc8); - } - else - { - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - addbyte(0x0f); /*MOVZX ECX, AH*/ - addbyte(0xb6); - addbyte(0xcc); - addbyte(0xc1); /*SHR EAX, 3*/ - addbyte(0xe8); - addbyte(3); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0xc1); /*SHL ECX, 3*/ - addbyte(0xe1); - addbyte(3); - addbyte(0x81); /*AND EAX, 0x001f*/ - addbyte(0xe0); - addlong(0x001f); - addbyte(0x81); /*AND EBX, 0xf800*/ - addbyte(0xe3); - addlong(0xf800); - addbyte(0x81); /*AND ECX, 0x07e0*/ - addbyte(0xe1); - addlong(0x07e0); - addbyte(0x09); /*OR EAX, EBX*/ - addbyte(0xd8); - addbyte(0x09); /*OR EAX, ECX*/ - addbyte(0xc8); - } - addbyte(0x8b); /*MOV ESI, fb_mem*/ - addbyte(0xb7); - addlong(offsetof(voodoo_state_t, fb_mem)); - addbyte(0x66); /*MOV [ESI+EDX*2], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x56); - } - - if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) - { - addbyte(0x66); /*MOV AX, new_depth*/ - addbyte(0x8b); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, new_depth)); - addbyte(0x8b); /*MOV ESI, aux_mem*/ - addbyte(0xb7); - addlong(offsetof(voodoo_state_t, aux_mem)); - addbyte(0x66); /*MOV [ESI+EDX*2], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x56); - } - - if (z_skip_pos) - *(uint32_t *)&code_block[z_skip_pos] = (block_pos - z_skip_pos) - 4; - if (a_skip_pos) - *(uint32_t *)&code_block[a_skip_pos] = (block_pos - a_skip_pos) - 4; - if (chroma_skip_pos) - *(uint32_t *)&code_block[chroma_skip_pos] = (block_pos - chroma_skip_pos) - 4; - - - addbyte(0x8b); /*MOV ESI, [ESP+8]*/ - addbyte(0x74); - addbyte(0x24); - addbyte(8+16); - - if (voodoo->dual_tmus) - { - addbyte(0xf3); /*MOVDQU XMM3, state->tmu1_s[EDI]*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tmu1_s)); - addbyte(0xf3); /*MOVQ XMM4, state->tmu1_w[EDI]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xa7); - addlong(offsetof(voodoo_state_t, tmu1_w)); - addbyte(0xf3); /*MOVDQU XMM5, params->tmu[1].dSdX[ESI]*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0xae); - addlong(offsetof(voodoo_params_t, tmu[1].dSdX)); - addbyte(0xf3); /*MOVQ XMM6, params->tmu[1].dWdX[ESI]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xb6); - addlong(offsetof(voodoo_params_t, tmu[1].dWdX)); - if (state->xdir > 0) - { - addbyte(0x66); /*PADDQ XMM3, XMM5*/ - addbyte(0x0f); - addbyte(0xd4); - addbyte(0xdd); - addbyte(0x66); /*PADDQ XMM4, XMM6*/ - addbyte(0x0f); - addbyte(0xd4); - addbyte(0xe6); - } - else - { - addbyte(0x66); /*PSUBQ XMM3, XMM5*/ - addbyte(0x0f); - addbyte(0xfb); - addbyte(0xdd); - addbyte(0x66); /*PSUBQ XMM4, XMM6*/ - addbyte(0x0f); - addbyte(0xfb); - addbyte(0xe6); - } - addbyte(0xf3); /*MOVDQU state->tmu1_s, XMM3*/ - addbyte(0x0f); - addbyte(0x7f); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tmu1_s)); - addbyte(0x66); /*MOVQ state->tmu1_w, XMM4*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0xa7); - addlong(offsetof(voodoo_state_t, tmu1_w)); - } - - addbyte(0xf3); /*MOVDQU XMM1, state->ib[EDI]*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, ib)); - addbyte(0xf3); /*MOVDQU XMM3, state->tmu0_s[EDI]*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tmu0_s)); - addbyte(0xf3); /*MOVQ XMM4, state->tmu0_w[EDI]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xa7); - addlong(offsetof(voodoo_state_t, tmu0_w)); - addbyte(0xf3); /*MOVDQU XMM0, params->dBdX[ESI]*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x86); - addlong(offsetof(voodoo_params_t, dBdX)); - addbyte(0x8b); /*MOV EAX, params->dZdX[ESI]*/ - addbyte(0x86); - addlong(offsetof(voodoo_params_t, dZdX)); - addbyte(0xf3); /*MOVDQU XMM5, params->tmu[0].dSdX[ESI]*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0xae); - addlong(offsetof(voodoo_params_t, tmu[0].dSdX)); - addbyte(0xf3); /*MOVQ XMM6, params->tmu[0].dWdX[ESI]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xb6); - addlong(offsetof(voodoo_params_t, tmu[0].dWdX)); - - if (state->xdir > 0) - { - addbyte(0x66); /*PADDD XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0xfe); - addbyte(0xc8); - } - else - { - addbyte(0x66); /*PSUBD XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0xfa); - addbyte(0xc8); - } - - addbyte(0xf3); /*MOVQ XMM0, state->w*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, w)); - addbyte(0xf3); /*MOVDQU state->ib, XMM1*/ - addbyte(0x0f); - addbyte(0x7f); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, ib)); - addbyte(0xf3); /*MOVQ XMM7, params->dWdX*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xbe); - addlong(offsetof(voodoo_params_t, dWdX)); - - if (state->xdir > 0) - { - addbyte(0x66); /*PADDQ XMM3, XMM5*/ - addbyte(0x0f); - addbyte(0xd4); - addbyte(0xdd); - addbyte(0x66); /*PADDQ XMM4, XMM6*/ - addbyte(0x0f); - addbyte(0xd4); - addbyte(0xe6); - addbyte(0x66); /*PADDQ XMM0, XMM7*/ - addbyte(0x0f); - addbyte(0xd4); - addbyte(0xc7); - addbyte(0x01); /*ADD state->z[EDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, z)); - } - else - { - addbyte(0x66); /*PSUBQ XMM3, XMM5*/ - addbyte(0x0f); - addbyte(0xfb); - addbyte(0xdd); - addbyte(0x66); /*PSUBQ XMM4, XMM6*/ - addbyte(0x0f); - addbyte(0xfb); - addbyte(0xe6); - addbyte(0x66); /*PSUBQ XMM0, XMM7*/ - addbyte(0x0f); - addbyte(0xfb); - addbyte(0xc7); - addbyte(0x29); /*SUB state->z[EDI], EAX*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, z)); - } - - addbyte(0xf3); /*MOVDQU state->tmu0_s, XMM3*/ - addbyte(0x0f); - addbyte(0x7f); - addbyte(0x9f); - addlong(offsetof(voodoo_state_t, tmu0_s)); - addbyte(0x66); /*MOVQ state->tmu0_w, XMM4*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0xa7); - addlong(offsetof(voodoo_state_t, tmu0_w)); - addbyte(0x66); /*MOVQ state->w, XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x87); - addlong(offsetof(voodoo_state_t, w)); - - addbyte(0x83); /*ADD state->pixel_count[EDI], 1*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, pixel_count)); - addbyte(1); - - if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) - { - if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || - (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) - { - addbyte(0x83); /*ADD state->texel_count[EDI], 1*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, texel_count)); - addbyte(1); - } - else - { - addbyte(0x83); /*ADD state->texel_count[EDI], 2*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, texel_count)); - addbyte(2); - } - } - addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, x)); - - if (state->xdir > 0) - { - addbyte(0x83); /*ADD state->x[EDI], 1*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, x)); - addbyte(1); - } - else - { - addbyte(0x83); /*SUB state->x[EDI], 1*/ - addbyte(0xaf); - addlong(offsetof(voodoo_state_t, x)); - addbyte(1); - } - - addbyte(0x3b); /*CMP EAX, state->x2[EDI]*/ - addbyte(0x87); - addlong(offsetof(voodoo_state_t, x2)); - addbyte(0x0f); /*JNZ loop_jump_pos*/ - addbyte(0x85); - addlong(loop_jump_pos - (block_pos + 4)); - - addbyte(0x5b); /*POP EBX*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5d); /*POP EBP*/ - - addbyte(0xC3); /*RET*/ - - if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) - cs = cs; -} -static int voodoo_recomp = 0; - -static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even) -{ - int c; - int b = last_block[odd_even]; - voodoo_x86_data_t *data; - voodoo_x86_data_t *codegen_data = voodoo->codegen_data; - - for (c = 0; c < 8; c++) - { - data = &codegen_data[odd_even + b*2]; - - if (state->xdir == data->xdir && - params->alphaMode == data->alphaMode && - params->fbzMode == data->fbzMode && - params->fogMode == data->fogMode && - params->fbzColorPath == data->fbzColorPath && - (voodoo->trexInit1[0] & (1 << 18)) == data->trexInit1 && - params->textureMode[0] == data->textureMode[0] && - params->textureMode[1] == data->textureMode[1] && - (params->tLOD[0] & LOD_MASK) == data->tLOD[0] && - (params->tLOD[1] & LOD_MASK) == data->tLOD[1]) - { - last_block[odd_even] = b; - return data->code_block; - } - - b = (b + 1) & 7; - } -voodoo_recomp++; - data = &codegen_data[odd_even + next_block_to_write[odd_even]*2]; -// code_block = data->code_block; - - voodoo_generate(data->code_block, voodoo, params, state, depth_op); - - data->xdir = state->xdir; - data->alphaMode = params->alphaMode; - data->fbzMode = params->fbzMode; - data->fogMode = params->fogMode; - data->fbzColorPath = params->fbzColorPath; - data->trexInit1 = voodoo->trexInit1[0] & (1 << 18); - data->textureMode[0] = params->textureMode[0]; - data->textureMode[1] = params->textureMode[1]; - data->tLOD[0] = params->tLOD[0] & LOD_MASK; - data->tLOD[1] = params->tLOD[1] & LOD_MASK; - - next_block_to_write[odd_even] = (next_block_to_write[odd_even] + 1) & 7; - - return data->code_block; -} - -static void voodoo_codegen_init(voodoo_t *voodoo) -{ - int c; -#ifdef __linux__ - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); -#endif - -#if defined WIN32 || defined _WIN32 || defined _WIN32 - voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else - voodoo->codegen_data = malloc(sizeof(voodoo_x86_data_t) * BLOCK_NUM*2); -#endif - -#ifdef __linux__ - start = (void *)((long)voodoo->codegen_data & pagemask); - len = ((sizeof(voodoo_x86_data_t) * BLOCK_NUM*2) + pagesize) & pagemask; - if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - { - perror("mprotect"); - exit(-1); - } -#endif - - for (c = 0; c < 256; c++) - { - int d[4]; - int _ds = c & 0xf; - int dt = c >> 4; - - alookup[c] = _mm_set_epi32(0, 0, c | (c << 16), c | (c << 16)); - aminuslookup[c] = _mm_set_epi32(0, 0, (255-c) | ((255-c) << 16), (255-c) | ((255-c) << 16)); - - d[0] = (16 - _ds) * (16 - dt); - d[1] = _ds * (16 - dt); - d[2] = (16 - _ds) * dt; - d[3] = _ds * dt; - - bilinear_lookup[c*2] = _mm_set_epi32(d[1] | (d[1] << 16), d[1] | (d[1] << 16), d[0] | (d[0] << 16), d[0] | (d[0] << 16)); - bilinear_lookup[c*2 + 1] = _mm_set_epi32(d[3] | (d[3] << 16), d[3] | (d[3] << 16), d[2] | (d[2] << 16), d[2] | (d[2] << 16)); - } - alookup[256] = _mm_set_epi32(0, 0, 256 | (256 << 16), 256 | (256 << 16)); - xmm_00_ff_w[0] = _mm_set_epi32(0, 0, 0, 0); - xmm_00_ff_w[1] = _mm_set_epi32(0, 0, 0xff | (0xff << 16), 0xff | (0xff << 16)); -} - -static void voodoo_codegen_close(voodoo_t *voodoo) -{ -#if defined WIN32 || defined _WIN32 || defined _WIN32 - VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); -#else - free(voodoo->codegen_data); -#endif -} diff --git a/backup code/video - Cópia/vid_voodoo_dither.h b/backup code/video - Cópia/vid_voodoo_dither.h deleted file mode 100644 index 21baf772b..000000000 --- a/backup code/video - Cópia/vid_voodoo_dither.h +++ /dev/null @@ -1,5136 +0,0 @@ -uint8_t dither_rb[256][4][4] = -{ - { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - }, - { - {0, 0, 0, 0}, - {0, 0, 1, 0}, - {0, 0, 0, 0}, - {1, 0, 0, 0}, - }, - { - {0, 0, 0, 0}, - {1, 0, 1, 0}, - {0, 0, 0, 0}, - {1, 0, 1, 0}, - }, - { - {0, 0, 0, 1}, - {1, 0, 1, 0}, - {0, 1, 0, 0}, - {1, 0, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 0, 1, 0}, - {0, 1, 0, 1}, - {1, 0, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 0, 1, 1}, - {0, 1, 0, 1}, - {1, 1, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 1, 1, 1}, - {0, 1, 0, 1}, - {1, 1, 1, 1}, - }, - { - {0, 1, 1, 1}, - {1, 1, 1, 1}, - {1, 1, 0, 1}, - {1, 1, 1, 1}, - }, - { - {1, 1, 1, 1}, - {1, 1, 1, 1}, - {1, 1, 1, 1}, - {1, 1, 1, 1}, - }, - { - {1, 1, 1, 1}, - {1, 1, 2, 1}, - {1, 1, 1, 1}, - {2, 1, 1, 1}, - }, - { - {1, 1, 1, 1}, - {2, 1, 2, 1}, - {1, 1, 1, 1}, - {2, 1, 2, 1}, - }, - { - {1, 1, 1, 2}, - {2, 1, 2, 1}, - {1, 2, 1, 1}, - {2, 1, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 1, 2, 1}, - {1, 2, 1, 2}, - {2, 1, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 1, 2, 2}, - {1, 2, 1, 2}, - {2, 2, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 2, 2, 2}, - {1, 2, 1, 2}, - {2, 2, 2, 2}, - }, - { - {1, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 1, 2}, - {2, 2, 2, 2}, - }, - { - {1, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - }, - { - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {3, 2, 2, 2}, - }, - { - {2, 2, 2, 2}, - {2, 2, 3, 2}, - {2, 2, 2, 2}, - {3, 2, 3, 2}, - }, - { - {2, 2, 2, 2}, - {3, 2, 3, 2}, - {2, 3, 2, 2}, - {3, 2, 3, 2}, - }, - { - {2, 2, 2, 3}, - {3, 2, 3, 2}, - {2, 3, 2, 3}, - {3, 2, 3, 2}, - }, - { - {2, 3, 2, 3}, - {3, 2, 3, 2}, - {2, 3, 2, 3}, - {3, 3, 3, 2}, - }, - { - {2, 3, 2, 3}, - {3, 2, 3, 3}, - {2, 3, 2, 3}, - {3, 3, 3, 3}, - }, - { - {2, 3, 2, 3}, - {3, 3, 3, 3}, - {3, 3, 2, 3}, - {3, 3, 3, 3}, - }, - { - {2, 3, 3, 3}, - {3, 3, 3, 3}, - {3, 3, 3, 3}, - {3, 3, 3, 3}, - }, - { - {3, 3, 3, 3}, - {3, 3, 3, 3}, - {3, 3, 3, 3}, - {4, 3, 3, 3}, - }, - { - {3, 3, 3, 3}, - {3, 3, 4, 3}, - {3, 3, 3, 3}, - {4, 3, 4, 3}, - }, - { - {3, 3, 3, 3}, - {4, 3, 4, 3}, - {3, 4, 3, 3}, - {4, 3, 4, 3}, - }, - { - {3, 3, 3, 4}, - {4, 3, 4, 3}, - {3, 4, 3, 4}, - {4, 3, 4, 3}, - }, - { - {3, 4, 3, 4}, - {4, 3, 4, 3}, - {3, 4, 3, 4}, - {4, 4, 4, 3}, - }, - { - {3, 4, 3, 4}, - {4, 3, 4, 4}, - {3, 4, 3, 4}, - {4, 4, 4, 4}, - }, - { - {3, 4, 3, 4}, - {4, 4, 4, 4}, - {4, 4, 3, 4}, - {4, 4, 4, 4}, - }, - { - {3, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 3, 4}, - {4, 4, 4, 4}, - }, - { - {4, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 4, 4}, - }, - { - {4, 4, 4, 4}, - {4, 4, 5, 4}, - {4, 4, 4, 4}, - {5, 4, 4, 4}, - }, - { - {4, 4, 4, 4}, - {5, 4, 5, 4}, - {4, 4, 4, 4}, - {5, 4, 5, 4}, - }, - { - {4, 4, 4, 5}, - {5, 4, 5, 4}, - {4, 5, 4, 4}, - {5, 4, 5, 4}, - }, - { - {4, 5, 4, 5}, - {5, 4, 5, 4}, - {4, 5, 4, 5}, - {5, 4, 5, 4}, - }, - { - {4, 5, 4, 5}, - {5, 4, 5, 5}, - {4, 5, 4, 5}, - {5, 5, 5, 4}, - }, - { - {4, 5, 4, 5}, - {5, 5, 5, 5}, - {4, 5, 4, 5}, - {5, 5, 5, 5}, - }, - { - {4, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 4, 5}, - {5, 5, 5, 5}, - }, - { - {5, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 5, 5}, - }, - { - {5, 5, 5, 5}, - {5, 5, 6, 5}, - {5, 5, 5, 5}, - {6, 5, 5, 5}, - }, - { - {5, 5, 5, 5}, - {6, 5, 6, 5}, - {5, 5, 5, 5}, - {6, 5, 6, 5}, - }, - { - {5, 5, 5, 6}, - {6, 5, 6, 5}, - {5, 6, 5, 5}, - {6, 5, 6, 5}, - }, - { - {5, 6, 5, 6}, - {6, 5, 6, 5}, - {5, 6, 5, 6}, - {6, 5, 6, 5}, - }, - { - {5, 6, 5, 6}, - {6, 5, 6, 6}, - {5, 6, 5, 6}, - {6, 6, 6, 5}, - }, - { - {5, 6, 5, 6}, - {6, 6, 6, 6}, - {5, 6, 5, 6}, - {6, 6, 6, 6}, - }, - { - {5, 6, 5, 6}, - {6, 6, 6, 6}, - {6, 6, 5, 6}, - {6, 6, 6, 6}, - }, - { - {5, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - }, - { - {6, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - {7, 6, 6, 6}, - }, - { - {6, 6, 6, 6}, - {6, 6, 7, 6}, - {6, 6, 6, 6}, - {7, 6, 7, 6}, - }, - { - {6, 6, 6, 6}, - {7, 6, 7, 6}, - {6, 7, 6, 6}, - {7, 6, 7, 6}, - }, - { - {6, 6, 6, 7}, - {7, 6, 7, 6}, - {6, 7, 6, 7}, - {7, 6, 7, 6}, - }, - { - {6, 7, 6, 7}, - {7, 6, 7, 6}, - {6, 7, 6, 7}, - {7, 7, 7, 6}, - }, - { - {6, 7, 6, 7}, - {7, 6, 7, 7}, - {6, 7, 6, 7}, - {7, 7, 7, 7}, - }, - { - {6, 7, 6, 7}, - {7, 7, 7, 7}, - {7, 7, 6, 7}, - {7, 7, 7, 7}, - }, - { - {6, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - }, - { - {7, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - {8, 7, 7, 7}, - }, - { - {7, 7, 7, 7}, - {7, 7, 8, 7}, - {7, 7, 7, 7}, - {8, 7, 8, 7}, - }, - { - {7, 7, 7, 7}, - {8, 7, 8, 7}, - {7, 8, 7, 7}, - {8, 7, 8, 7}, - }, - { - {7, 7, 7, 8}, - {8, 7, 8, 7}, - {7, 8, 7, 8}, - {8, 7, 8, 7}, - }, - { - {7, 8, 7, 8}, - {8, 7, 8, 7}, - {7, 8, 7, 8}, - {8, 8, 8, 7}, - }, - { - {7, 8, 7, 8}, - {8, 7, 8, 8}, - {7, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {7, 8, 7, 8}, - {8, 8, 8, 8}, - {7, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {7, 8, 8, 8}, - {8, 8, 8, 8}, - {8, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {8, 8, 8, 8}, - {8, 8, 8, 8}, - {8, 8, 8, 8}, - {8, 8, 8, 8}, - }, - { - {8, 8, 8, 8}, - {8, 8, 9, 8}, - {8, 8, 8, 8}, - {9, 8, 8, 8}, - }, - { - {8, 8, 8, 8}, - {9, 8, 9, 8}, - {8, 8, 8, 8}, - {9, 8, 9, 8}, - }, - { - {8, 8, 8, 9}, - {9, 8, 9, 8}, - {8, 9, 8, 8}, - {9, 8, 9, 8}, - }, - { - {8, 9, 8, 9}, - {9, 8, 9, 8}, - {8, 9, 8, 9}, - {9, 8, 9, 8}, - }, - { - {8, 9, 8, 9}, - {9, 8, 9, 9}, - {8, 9, 8, 9}, - {9, 9, 9, 8}, - }, - { - {8, 9, 8, 9}, - {9, 9, 9, 9}, - {8, 9, 8, 9}, - {9, 9, 9, 9}, - }, - { - {8, 9, 9, 9}, - {9, 9, 9, 9}, - {9, 9, 8, 9}, - {9, 9, 9, 9}, - }, - { - {9, 9, 9, 9}, - {9, 9, 9, 9}, - {9, 9, 9, 9}, - {9, 9, 9, 9}, - }, - { - {9, 9, 9, 9}, - {9, 9, 10, 9}, - {9, 9, 9, 9}, - {10, 9, 9, 9}, - }, - { - {9, 9, 9, 9}, - {10, 9, 10, 9}, - {9, 9, 9, 9}, - {10, 9, 10, 9}, - }, - { - {9, 9, 9, 10}, - {10, 9, 10, 9}, - {9, 10, 9, 9}, - {10, 9, 10, 9}, - }, - { - {9, 10, 9, 10}, - {10, 9, 10, 9}, - {9, 10, 9, 10}, - {10, 9, 10, 9}, - }, - { - {9, 10, 9, 10}, - {10, 9, 10, 10}, - {9, 10, 9, 10}, - {10, 10, 10, 9}, - }, - { - {9, 10, 9, 10}, - {10, 9, 10, 10}, - {9, 10, 9, 10}, - {10, 10, 10, 10}, - }, - { - {9, 10, 9, 10}, - {10, 10, 10, 10}, - {10, 10, 9, 10}, - {10, 10, 10, 10}, - }, - { - {9, 10, 10, 10}, - {10, 10, 10, 10}, - {10, 10, 10, 10}, - {10, 10, 10, 10}, - }, - { - {10, 10, 10, 10}, - {10, 10, 10, 10}, - {10, 10, 10, 10}, - {11, 10, 10, 10}, - }, - { - {10, 10, 10, 10}, - {10, 10, 11, 10}, - {10, 10, 10, 10}, - {11, 10, 11, 10}, - }, - { - {10, 10, 10, 10}, - {11, 10, 11, 10}, - {10, 11, 10, 10}, - {11, 10, 11, 10}, - }, - { - {10, 10, 10, 11}, - {11, 10, 11, 10}, - {10, 11, 10, 11}, - {11, 10, 11, 10}, - }, - { - {10, 11, 10, 11}, - {11, 10, 11, 10}, - {10, 11, 10, 11}, - {11, 11, 11, 10}, - }, - { - {10, 11, 10, 11}, - {11, 10, 11, 11}, - {10, 11, 10, 11}, - {11, 11, 11, 11}, - }, - { - {10, 11, 10, 11}, - {11, 11, 11, 11}, - {11, 11, 10, 11}, - {11, 11, 11, 11}, - }, - { - {10, 11, 11, 11}, - {11, 11, 11, 11}, - {11, 11, 11, 11}, - {11, 11, 11, 11}, - }, - { - {11, 11, 11, 11}, - {11, 11, 11, 11}, - {11, 11, 11, 11}, - {12, 11, 11, 11}, - }, - { - {11, 11, 11, 11}, - {11, 11, 12, 11}, - {11, 11, 11, 11}, - {12, 11, 12, 11}, - }, - { - {11, 11, 11, 11}, - {12, 11, 12, 11}, - {11, 12, 11, 11}, - {12, 11, 12, 11}, - }, - { - {11, 11, 11, 12}, - {12, 11, 12, 11}, - {11, 12, 11, 12}, - {12, 11, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 11, 12, 11}, - {11, 12, 11, 12}, - {12, 12, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 11, 12, 12}, - {11, 12, 11, 12}, - {12, 12, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 12, 12, 12}, - {11, 12, 11, 12}, - {12, 12, 12, 12}, - }, - { - {11, 12, 12, 12}, - {12, 12, 12, 12}, - {12, 12, 11, 12}, - {12, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {12, 12, 12, 12}, - {12, 12, 12, 12}, - {12, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {12, 12, 13, 12}, - {12, 12, 12, 12}, - {13, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {13, 12, 13, 12}, - {12, 12, 12, 12}, - {13, 12, 13, 12}, - }, - { - {12, 12, 12, 13}, - {13, 12, 13, 12}, - {12, 13, 12, 12}, - {13, 12, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 12, 13, 12}, - {12, 13, 12, 13}, - {13, 12, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 12, 13, 13}, - {12, 13, 12, 13}, - {13, 13, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 13, 13, 13}, - {12, 13, 12, 13}, - {13, 13, 13, 13}, - }, - { - {12, 13, 13, 13}, - {13, 13, 13, 13}, - {13, 13, 12, 13}, - {13, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {13, 13, 13, 13}, - {13, 13, 13, 13}, - {13, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {13, 13, 14, 13}, - {13, 13, 13, 13}, - {14, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {14, 13, 14, 13}, - {13, 13, 13, 13}, - {14, 13, 14, 13}, - }, - { - {13, 13, 13, 14}, - {14, 13, 14, 13}, - {13, 14, 13, 13}, - {14, 13, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 13, 14, 13}, - {13, 14, 13, 14}, - {14, 13, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 13, 14, 13}, - {13, 14, 13, 14}, - {14, 14, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 13, 14, 14}, - {13, 14, 13, 14}, - {14, 14, 14, 14}, - }, - { - {13, 14, 13, 14}, - {14, 14, 14, 14}, - {14, 14, 13, 14}, - {14, 14, 14, 14}, - }, - { - {13, 14, 14, 14}, - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {14, 14, 14, 14}, - }, - { - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {15, 14, 14, 14}, - }, - { - {14, 14, 14, 14}, - {14, 14, 15, 14}, - {14, 14, 14, 14}, - {15, 14, 15, 14}, - }, - { - {14, 14, 14, 14}, - {15, 14, 15, 14}, - {14, 15, 14, 14}, - {15, 14, 15, 14}, - }, - { - {14, 14, 14, 15}, - {15, 14, 15, 14}, - {14, 15, 14, 15}, - {15, 14, 15, 14}, - }, - { - {14, 15, 14, 15}, - {15, 14, 15, 14}, - {14, 15, 14, 15}, - {15, 15, 15, 14}, - }, - { - {14, 15, 14, 15}, - {15, 14, 15, 15}, - {14, 15, 14, 15}, - {15, 15, 15, 15}, - }, - { - {14, 15, 14, 15}, - {15, 15, 15, 15}, - {15, 15, 14, 15}, - {15, 15, 15, 15}, - }, - { - {14, 15, 15, 15}, - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {15, 15, 15, 15}, - }, - { - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {16, 15, 15, 15}, - }, - { - {15, 15, 15, 15}, - {15, 15, 16, 15}, - {15, 15, 15, 15}, - {16, 15, 16, 15}, - }, - { - {15, 15, 15, 15}, - {16, 15, 16, 15}, - {15, 16, 15, 15}, - {16, 15, 16, 15}, - }, - { - {15, 15, 15, 16}, - {16, 15, 16, 15}, - {15, 16, 15, 16}, - {16, 15, 16, 15}, - }, - { - {15, 16, 15, 16}, - {16, 15, 16, 15}, - {15, 16, 15, 16}, - {16, 16, 16, 15}, - }, - { - {15, 16, 15, 16}, - {16, 15, 16, 16}, - {15, 16, 15, 16}, - {16, 16, 16, 16}, - }, - { - {15, 16, 15, 16}, - {16, 16, 16, 16}, - {16, 16, 15, 16}, - {16, 16, 16, 16}, - }, - { - {15, 16, 16, 16}, - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {16, 16, 16, 16}, - }, - { - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {17, 16, 16, 16}, - }, - { - {16, 16, 16, 16}, - {16, 16, 17, 16}, - {16, 16, 16, 16}, - {17, 16, 17, 16}, - }, - { - {16, 16, 16, 16}, - {17, 16, 17, 16}, - {16, 17, 16, 16}, - {17, 16, 17, 16}, - }, - { - {16, 16, 16, 17}, - {17, 16, 17, 16}, - {16, 17, 16, 17}, - {17, 16, 17, 16}, - }, - { - {16, 17, 16, 17}, - {17, 16, 17, 16}, - {16, 17, 16, 17}, - {17, 17, 17, 16}, - }, - { - {16, 17, 16, 17}, - {17, 16, 17, 17}, - {16, 17, 16, 17}, - {17, 17, 17, 17}, - }, - { - {16, 17, 16, 17}, - {17, 17, 17, 17}, - {17, 17, 16, 17}, - {17, 17, 17, 17}, - }, - { - {16, 17, 17, 17}, - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {17, 17, 17, 17}, - }, - { - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {18, 17, 17, 17}, - }, - { - {17, 17, 17, 17}, - {17, 17, 18, 17}, - {17, 17, 17, 17}, - {18, 17, 18, 17}, - }, - { - {17, 17, 17, 17}, - {18, 17, 18, 17}, - {17, 18, 17, 17}, - {18, 17, 18, 17}, - }, - { - {17, 17, 17, 18}, - {18, 17, 18, 17}, - {17, 18, 17, 18}, - {18, 17, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 17, 18, 17}, - {17, 18, 17, 18}, - {18, 17, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 17, 18, 18}, - {17, 18, 17, 18}, - {18, 18, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 18, 18, 18}, - {17, 18, 17, 18}, - {18, 18, 18, 18}, - }, - { - {17, 18, 18, 18}, - {18, 18, 18, 18}, - {18, 18, 17, 18}, - {18, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {18, 18, 18, 18}, - {18, 18, 18, 18}, - {18, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {18, 18, 19, 18}, - {18, 18, 18, 18}, - {19, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {19, 18, 19, 18}, - {18, 18, 18, 18}, - {19, 18, 19, 18}, - }, - { - {18, 18, 18, 19}, - {19, 18, 19, 18}, - {18, 19, 18, 18}, - {19, 18, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 18, 19, 18}, - {18, 19, 18, 19}, - {19, 18, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 18, 19, 19}, - {18, 19, 18, 19}, - {19, 19, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 19, 19, 19}, - {18, 19, 18, 19}, - {19, 19, 19, 19}, - }, - { - {18, 19, 19, 19}, - {19, 19, 19, 19}, - {19, 19, 18, 19}, - {19, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {19, 19, 19, 19}, - {19, 19, 19, 19}, - {19, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {19, 19, 20, 19}, - {19, 19, 19, 19}, - {20, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {20, 19, 20, 19}, - {19, 19, 19, 19}, - {20, 19, 20, 19}, - }, - { - {19, 19, 19, 20}, - {20, 19, 20, 19}, - {19, 20, 19, 19}, - {20, 19, 20, 19}, - }, - { - {19, 19, 19, 20}, - {20, 19, 20, 19}, - {19, 20, 19, 20}, - {20, 19, 20, 19}, - }, - { - {19, 20, 19, 20}, - {20, 19, 20, 19}, - {19, 20, 19, 20}, - {20, 20, 20, 19}, - }, - { - {19, 20, 19, 20}, - {20, 19, 20, 20}, - {19, 20, 19, 20}, - {20, 20, 20, 20}, - }, - { - {19, 20, 19, 20}, - {20, 20, 20, 20}, - {20, 20, 19, 20}, - {20, 20, 20, 20}, - }, - { - {19, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - }, - { - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {21, 20, 20, 20}, - }, - { - {20, 20, 20, 20}, - {20, 20, 21, 20}, - {20, 20, 20, 20}, - {21, 20, 21, 20}, - }, - { - {20, 20, 20, 20}, - {21, 20, 21, 20}, - {20, 21, 20, 20}, - {21, 20, 21, 20}, - }, - { - {20, 20, 20, 21}, - {21, 20, 21, 20}, - {20, 21, 20, 21}, - {21, 20, 21, 20}, - }, - { - {20, 21, 20, 21}, - {21, 20, 21, 20}, - {20, 21, 20, 21}, - {21, 21, 21, 20}, - }, - { - {20, 21, 20, 21}, - {21, 20, 21, 21}, - {20, 21, 20, 21}, - {21, 21, 21, 21}, - }, - { - {20, 21, 20, 21}, - {21, 21, 21, 21}, - {21, 21, 20, 21}, - {21, 21, 21, 21}, - }, - { - {20, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - }, - { - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {22, 21, 21, 21}, - }, - { - {21, 21, 21, 21}, - {21, 21, 22, 21}, - {21, 21, 21, 21}, - {22, 21, 22, 21}, - }, - { - {21, 21, 21, 21}, - {22, 21, 22, 21}, - {21, 22, 21, 21}, - {22, 21, 22, 21}, - }, - { - {21, 21, 21, 22}, - {22, 21, 22, 21}, - {21, 22, 21, 21}, - {22, 21, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 21, 22, 21}, - {21, 22, 21, 22}, - {22, 21, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 21, 22, 22}, - {21, 22, 21, 22}, - {22, 22, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 22, 22, 22}, - {21, 22, 21, 22}, - {22, 22, 22, 22}, - }, - { - {21, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 21, 22}, - {22, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {22, 22, 23, 22}, - {22, 22, 22, 22}, - {23, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {23, 22, 23, 22}, - {22, 22, 22, 22}, - {23, 22, 23, 22}, - }, - { - {22, 22, 22, 23}, - {23, 22, 23, 22}, - {22, 23, 22, 22}, - {23, 22, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 22, 23, 22}, - {22, 23, 22, 23}, - {23, 22, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 22, 23, 23}, - {22, 23, 22, 23}, - {23, 23, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 23, 23, 23}, - {22, 23, 22, 23}, - {23, 23, 23, 23}, - }, - { - {22, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 22, 23}, - {23, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {23, 23, 24, 23}, - {23, 23, 23, 23}, - {24, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {24, 23, 24, 23}, - {23, 23, 23, 23}, - {24, 23, 24, 23}, - }, - { - {23, 23, 23, 23}, - {24, 23, 24, 23}, - {23, 24, 23, 23}, - {24, 23, 24, 23}, - }, - { - {23, 23, 23, 24}, - {24, 23, 24, 23}, - {23, 24, 23, 24}, - {24, 23, 24, 23}, - }, - { - {23, 24, 23, 24}, - {24, 23, 24, 23}, - {23, 24, 23, 24}, - {24, 24, 24, 23}, - }, - { - {23, 24, 23, 24}, - {24, 23, 24, 24}, - {23, 24, 23, 24}, - {24, 24, 24, 24}, - }, - { - {23, 24, 23, 24}, - {24, 24, 24, 24}, - {24, 24, 23, 24}, - {24, 24, 24, 24}, - }, - { - {23, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - }, - { - {24, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - {25, 24, 24, 24}, - }, - { - {24, 24, 24, 24}, - {24, 24, 25, 24}, - {24, 24, 24, 24}, - {25, 24, 25, 24}, - }, - { - {24, 24, 24, 24}, - {25, 24, 25, 24}, - {24, 25, 24, 24}, - {25, 24, 25, 24}, - }, - { - {24, 24, 24, 25}, - {25, 24, 25, 24}, - {24, 25, 24, 25}, - {25, 24, 25, 24}, - }, - { - {24, 25, 24, 25}, - {25, 24, 25, 24}, - {24, 25, 24, 25}, - {25, 25, 25, 24}, - }, - { - {24, 25, 24, 25}, - {25, 24, 25, 25}, - {24, 25, 24, 25}, - {25, 25, 25, 25}, - }, - { - {24, 25, 24, 25}, - {25, 25, 25, 25}, - {25, 25, 24, 25}, - {25, 25, 25, 25}, - }, - { - {24, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - }, - { - {25, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - {26, 25, 25, 25}, - }, - { - {25, 25, 25, 25}, - {25, 25, 26, 25}, - {25, 25, 25, 25}, - {26, 25, 26, 25}, - }, - { - {25, 25, 25, 25}, - {26, 25, 26, 25}, - {25, 25, 25, 25}, - {26, 25, 26, 25}, - }, - { - {25, 25, 25, 26}, - {26, 25, 26, 25}, - {25, 26, 25, 25}, - {26, 25, 26, 25}, - }, - { - {25, 26, 25, 26}, - {26, 25, 26, 25}, - {25, 26, 25, 26}, - {26, 25, 26, 25}, - }, - { - {25, 26, 25, 26}, - {26, 25, 26, 26}, - {25, 26, 25, 26}, - {26, 26, 26, 25}, - }, - { - {25, 26, 25, 26}, - {26, 26, 26, 26}, - {25, 26, 25, 26}, - {26, 26, 26, 26}, - }, - { - {25, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 25, 26}, - {26, 26, 26, 26}, - }, - { - {26, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 26, 26}, - }, - { - {26, 26, 26, 26}, - {26, 26, 27, 26}, - {26, 26, 26, 26}, - {27, 26, 26, 26}, - }, - { - {26, 26, 26, 26}, - {27, 26, 27, 26}, - {26, 26, 26, 26}, - {27, 26, 27, 26}, - }, - { - {26, 26, 26, 27}, - {27, 26, 27, 26}, - {26, 27, 26, 26}, - {27, 26, 27, 26}, - }, - { - {26, 27, 26, 27}, - {27, 26, 27, 26}, - {26, 27, 26, 27}, - {27, 26, 27, 26}, - }, - { - {26, 27, 26, 27}, - {27, 26, 27, 27}, - {26, 27, 26, 27}, - {27, 27, 27, 26}, - }, - { - {26, 27, 26, 27}, - {27, 27, 27, 27}, - {26, 27, 26, 27}, - {27, 27, 27, 27}, - }, - { - {26, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 26, 27}, - {27, 27, 27, 27}, - }, - { - {27, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 27, 27}, - }, - { - {27, 27, 27, 27}, - {27, 27, 28, 27}, - {27, 27, 27, 27}, - {28, 27, 27, 27}, - }, - { - {27, 27, 27, 27}, - {27, 27, 28, 27}, - {27, 27, 27, 27}, - {28, 27, 28, 27}, - }, - { - {27, 27, 27, 27}, - {28, 27, 28, 27}, - {27, 28, 27, 27}, - {28, 27, 28, 27}, - }, - { - {27, 27, 27, 28}, - {28, 27, 28, 27}, - {27, 28, 27, 28}, - {28, 27, 28, 27}, - }, - { - {27, 28, 27, 28}, - {28, 27, 28, 27}, - {27, 28, 27, 28}, - {28, 28, 28, 27}, - }, - { - {27, 28, 27, 28}, - {28, 27, 28, 28}, - {27, 28, 27, 28}, - {28, 28, 28, 28}, - }, - { - {27, 28, 27, 28}, - {28, 28, 28, 28}, - {28, 28, 27, 28}, - {28, 28, 28, 28}, - }, - { - {27, 28, 28, 28}, - {28, 28, 28, 28}, - {28, 28, 28, 28}, - {28, 28, 28, 28}, - }, - { - {28, 28, 28, 28}, - {28, 28, 28, 28}, - {28, 28, 28, 28}, - {29, 28, 28, 28}, - }, - { - {28, 28, 28, 28}, - {28, 28, 29, 28}, - {28, 28, 28, 28}, - {29, 28, 29, 28}, - }, - { - {28, 28, 28, 28}, - {29, 28, 29, 28}, - {28, 29, 28, 28}, - {29, 28, 29, 28}, - }, - { - {28, 28, 28, 29}, - {29, 28, 29, 28}, - {28, 29, 28, 29}, - {29, 28, 29, 28}, - }, - { - {28, 29, 28, 29}, - {29, 28, 29, 28}, - {28, 29, 28, 29}, - {29, 29, 29, 28}, - }, - { - {28, 29, 28, 29}, - {29, 28, 29, 29}, - {28, 29, 28, 29}, - {29, 29, 29, 29}, - }, - { - {28, 29, 28, 29}, - {29, 29, 29, 29}, - {29, 29, 28, 29}, - {29, 29, 29, 29}, - }, - { - {28, 29, 29, 29}, - {29, 29, 29, 29}, - {29, 29, 29, 29}, - {29, 29, 29, 29}, - }, - { - {29, 29, 29, 29}, - {29, 29, 29, 29}, - {29, 29, 29, 29}, - {30, 29, 29, 29}, - }, - { - {29, 29, 29, 29}, - {29, 29, 30, 29}, - {29, 29, 29, 29}, - {30, 29, 29, 29}, - }, - { - {29, 29, 29, 29}, - {30, 29, 30, 29}, - {29, 29, 29, 29}, - {30, 29, 30, 29}, - }, - { - {29, 29, 29, 30}, - {30, 29, 30, 29}, - {29, 30, 29, 29}, - {30, 29, 30, 29}, - }, - { - {29, 30, 29, 30}, - {30, 29, 30, 29}, - {29, 30, 29, 30}, - {30, 29, 30, 29}, - }, - { - {29, 30, 29, 30}, - {30, 29, 30, 30}, - {29, 30, 29, 30}, - {30, 30, 30, 29}, - }, - { - {29, 30, 29, 30}, - {30, 30, 30, 30}, - {29, 30, 29, 30}, - {30, 30, 30, 30}, - }, - { - {29, 30, 30, 30}, - {30, 30, 30, 30}, - {30, 30, 29, 30}, - {30, 30, 30, 30}, - }, - { - {30, 30, 30, 30}, - {30, 30, 30, 30}, - {30, 30, 30, 30}, - {30, 30, 30, 30}, - }, - { - {30, 30, 30, 30}, - {30, 30, 31, 30}, - {30, 30, 30, 30}, - {31, 30, 30, 30}, - }, - { - {30, 30, 30, 30}, - {31, 30, 31, 30}, - {30, 30, 30, 30}, - {31, 30, 31, 30}, - }, - { - {30, 30, 30, 31}, - {31, 30, 31, 30}, - {30, 31, 30, 30}, - {31, 30, 31, 30}, - }, - { - {30, 31, 30, 31}, - {31, 30, 31, 30}, - {30, 31, 30, 31}, - {31, 30, 31, 30}, - }, - { - {30, 31, 30, 31}, - {31, 30, 31, 31}, - {30, 31, 30, 31}, - {31, 31, 31, 30}, - }, - { - {30, 31, 30, 31}, - {31, 31, 31, 31}, - {30, 31, 30, 31}, - {31, 31, 31, 31}, - }, - { - {30, 31, 31, 31}, - {31, 31, 31, 31}, - {31, 31, 30, 31}, - {31, 31, 31, 31}, - }, - { - {31, 31, 31, 31}, - {31, 31, 31, 31}, - {31, 31, 31, 31}, - {31, 31, 31, 31}, - }, -}; - -uint8_t dither_g[256][4][4] = -{ - { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - }, - { - {0, 0, 0, 0}, - {1, 0, 1, 0}, - {0, 0, 0, 0}, - {1, 0, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 0, 1, 0}, - {0, 1, 0, 1}, - {1, 0, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 1, 1, 1}, - {0, 1, 0, 1}, - {1, 1, 1, 1}, - }, - { - {1, 1, 1, 1}, - {1, 1, 1, 1}, - {1, 1, 1, 1}, - {1, 1, 1, 1}, - }, - { - {1, 1, 1, 1}, - {2, 1, 2, 1}, - {1, 1, 1, 1}, - {2, 1, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 1, 2, 1}, - {1, 2, 1, 2}, - {2, 1, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 2, 2, 2}, - {1, 2, 1, 2}, - {2, 2, 2, 2}, - }, - { - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - }, - { - {2, 2, 2, 2}, - {3, 2, 3, 2}, - {2, 2, 2, 2}, - {3, 2, 3, 2}, - }, - { - {2, 3, 2, 3}, - {3, 2, 3, 2}, - {2, 3, 2, 3}, - {3, 2, 3, 2}, - }, - { - {2, 3, 2, 3}, - {3, 3, 3, 3}, - {2, 3, 2, 3}, - {3, 3, 3, 3}, - }, - { - {3, 3, 3, 3}, - {3, 3, 3, 3}, - {3, 3, 3, 3}, - {3, 3, 3, 3}, - }, - { - {3, 3, 3, 3}, - {4, 3, 4, 3}, - {3, 3, 3, 3}, - {4, 3, 4, 3}, - }, - { - {3, 4, 3, 4}, - {4, 3, 4, 3}, - {3, 4, 3, 4}, - {4, 3, 4, 3}, - }, - { - {3, 4, 3, 4}, - {4, 4, 4, 4}, - {3, 4, 3, 4}, - {4, 4, 4, 4}, - }, - { - {3, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 4, 4}, - }, - { - {4, 4, 4, 4}, - {4, 4, 5, 4}, - {4, 4, 4, 4}, - {5, 4, 5, 4}, - }, - { - {4, 4, 4, 5}, - {5, 4, 5, 4}, - {4, 5, 4, 5}, - {5, 4, 5, 4}, - }, - { - {4, 5, 4, 5}, - {5, 4, 5, 5}, - {4, 5, 4, 5}, - {5, 5, 5, 5}, - }, - { - {4, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 5, 5}, - }, - { - {5, 5, 5, 5}, - {5, 5, 6, 5}, - {5, 5, 5, 5}, - {6, 5, 6, 5}, - }, - { - {5, 5, 5, 6}, - {6, 5, 6, 5}, - {5, 6, 5, 6}, - {6, 5, 6, 5}, - }, - { - {5, 6, 5, 6}, - {6, 5, 6, 6}, - {5, 6, 5, 6}, - {6, 6, 6, 6}, - }, - { - {5, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - }, - { - {6, 6, 6, 6}, - {6, 6, 7, 6}, - {6, 6, 6, 6}, - {7, 6, 7, 6}, - }, - { - {6, 6, 6, 7}, - {7, 6, 7, 6}, - {6, 7, 6, 7}, - {7, 6, 7, 6}, - }, - { - {6, 7, 6, 7}, - {7, 6, 7, 7}, - {6, 7, 6, 7}, - {7, 7, 7, 7}, - }, - { - {6, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - }, - { - {7, 7, 7, 7}, - {7, 7, 8, 7}, - {7, 7, 7, 7}, - {8, 7, 8, 7}, - }, - { - {7, 7, 7, 8}, - {8, 7, 8, 7}, - {7, 8, 7, 8}, - {8, 7, 8, 7}, - }, - { - {7, 8, 7, 8}, - {8, 7, 8, 8}, - {7, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {7, 8, 8, 8}, - {8, 8, 8, 8}, - {8, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {8, 8, 8, 8}, - {8, 8, 9, 8}, - {8, 8, 8, 8}, - {9, 8, 8, 8}, - }, - { - {8, 8, 8, 9}, - {9, 8, 9, 8}, - {8, 9, 8, 8}, - {9, 8, 9, 8}, - }, - { - {8, 9, 8, 9}, - {9, 8, 9, 9}, - {8, 9, 8, 9}, - {9, 9, 9, 8}, - }, - { - {8, 9, 9, 9}, - {9, 9, 9, 9}, - {9, 9, 8, 9}, - {9, 9, 9, 9}, - }, - { - {9, 9, 9, 9}, - {9, 9, 10, 9}, - {9, 9, 9, 9}, - {10, 9, 9, 9}, - }, - { - {9, 9, 9, 10}, - {10, 9, 10, 9}, - {9, 10, 9, 9}, - {10, 9, 10, 9}, - }, - { - {9, 10, 9, 10}, - {10, 9, 10, 10}, - {9, 10, 9, 10}, - {10, 10, 10, 9}, - }, - { - {9, 10, 10, 10}, - {10, 10, 10, 10}, - {10, 10, 9, 10}, - {10, 10, 10, 10}, - }, - { - {10, 10, 10, 10}, - {10, 10, 11, 10}, - {10, 10, 10, 10}, - {11, 10, 10, 10}, - }, - { - {10, 10, 10, 11}, - {11, 10, 11, 10}, - {10, 11, 10, 10}, - {11, 10, 11, 10}, - }, - { - {10, 11, 10, 11}, - {11, 10, 11, 11}, - {10, 11, 10, 11}, - {11, 11, 11, 10}, - }, - { - {10, 11, 11, 11}, - {11, 11, 11, 11}, - {11, 11, 10, 11}, - {11, 11, 11, 11}, - }, - { - {11, 11, 11, 11}, - {11, 11, 12, 11}, - {11, 11, 11, 11}, - {12, 11, 11, 11}, - }, - { - {11, 11, 11, 12}, - {12, 11, 12, 11}, - {11, 12, 11, 11}, - {12, 11, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 11, 12, 12}, - {11, 12, 11, 12}, - {12, 12, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 12, 12, 12}, - {12, 12, 11, 12}, - {12, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {12, 12, 12, 12}, - {12, 12, 12, 12}, - {13, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {13, 12, 13, 12}, - {12, 13, 12, 12}, - {13, 12, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 12, 13, 12}, - {12, 13, 12, 13}, - {13, 13, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 13, 13, 13}, - {13, 13, 12, 13}, - {13, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {13, 13, 13, 13}, - {13, 13, 13, 13}, - {14, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {14, 13, 14, 13}, - {13, 14, 13, 13}, - {14, 13, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 13, 14, 13}, - {13, 14, 13, 14}, - {14, 14, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 14, 14, 14}, - {14, 14, 13, 14}, - {14, 14, 14, 14}, - }, - { - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {15, 14, 14, 14}, - }, - { - {14, 14, 14, 14}, - {15, 14, 15, 14}, - {14, 15, 14, 14}, - {15, 14, 15, 14}, - }, - { - {14, 15, 14, 15}, - {15, 14, 15, 14}, - {14, 15, 14, 15}, - {15, 15, 15, 14}, - }, - { - {14, 15, 14, 15}, - {15, 15, 15, 15}, - {15, 15, 14, 15}, - {15, 15, 15, 15}, - }, - { - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {16, 15, 15, 15}, - }, - { - {15, 15, 15, 15}, - {16, 15, 16, 15}, - {15, 16, 15, 15}, - {16, 15, 16, 15}, - }, - { - {15, 16, 15, 16}, - {16, 15, 16, 15}, - {15, 16, 15, 16}, - {16, 16, 16, 15}, - }, - { - {15, 16, 15, 16}, - {16, 16, 16, 16}, - {16, 16, 15, 16}, - {16, 16, 16, 16}, - }, - { - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {17, 16, 16, 16}, - }, - { - {16, 16, 16, 16}, - {17, 16, 17, 16}, - {16, 17, 16, 16}, - {17, 16, 17, 16}, - }, - { - {16, 17, 16, 17}, - {17, 16, 17, 16}, - {16, 17, 16, 17}, - {17, 17, 17, 16}, - }, - { - {16, 17, 16, 17}, - {17, 17, 17, 17}, - {17, 17, 16, 17}, - {17, 17, 17, 17}, - }, - { - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {18, 17, 17, 17}, - }, - { - {17, 17, 17, 17}, - {18, 17, 18, 17}, - {17, 18, 17, 17}, - {18, 17, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 17, 18, 17}, - {17, 18, 17, 18}, - {18, 18, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 18, 18, 18}, - {18, 18, 17, 18}, - {18, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {18, 18, 18, 18}, - {18, 18, 18, 18}, - {19, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {19, 18, 19, 18}, - {18, 19, 18, 18}, - {19, 18, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 18, 19, 18}, - {18, 19, 18, 19}, - {19, 19, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 19, 19, 19}, - {19, 19, 18, 19}, - {19, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {19, 19, 19, 19}, - {19, 19, 19, 19}, - {20, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {20, 19, 20, 19}, - {19, 20, 19, 19}, - {20, 19, 20, 19}, - }, - { - {19, 20, 19, 20}, - {20, 19, 20, 19}, - {19, 20, 19, 20}, - {20, 20, 20, 19}, - }, - { - {19, 20, 19, 20}, - {20, 20, 20, 20}, - {19, 20, 19, 20}, - {20, 20, 20, 20}, - }, - { - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - }, - { - {20, 20, 20, 20}, - {21, 20, 21, 20}, - {20, 20, 20, 20}, - {21, 20, 21, 20}, - }, - { - {20, 21, 20, 21}, - {21, 20, 21, 20}, - {20, 21, 20, 21}, - {21, 20, 21, 20}, - }, - { - {20, 21, 20, 21}, - {21, 21, 21, 21}, - {20, 21, 20, 21}, - {21, 21, 21, 21}, - }, - { - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - }, - { - {21, 21, 21, 21}, - {22, 21, 22, 21}, - {21, 21, 21, 21}, - {22, 21, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 21, 22, 21}, - {21, 22, 21, 22}, - {22, 21, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 22, 22, 22}, - {21, 22, 21, 22}, - {22, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {23, 22, 23, 22}, - {22, 22, 22, 22}, - {23, 22, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 22, 23, 22}, - {22, 23, 22, 23}, - {23, 22, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 23, 23, 23}, - {22, 23, 22, 23}, - {23, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {24, 23, 24, 23}, - {23, 23, 23, 23}, - {24, 23, 24, 23}, - }, - { - {23, 24, 23, 24}, - {24, 23, 24, 23}, - {23, 24, 23, 24}, - {24, 23, 24, 23}, - }, - { - {23, 24, 23, 24}, - {24, 23, 24, 24}, - {23, 24, 23, 24}, - {24, 24, 24, 24}, - }, - { - {23, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - }, - { - {24, 24, 24, 24}, - {24, 24, 25, 24}, - {24, 24, 24, 24}, - {25, 24, 25, 24}, - }, - { - {24, 24, 24, 25}, - {25, 24, 25, 24}, - {24, 25, 24, 25}, - {25, 24, 25, 24}, - }, - { - {24, 25, 24, 25}, - {25, 24, 25, 25}, - {24, 25, 24, 25}, - {25, 25, 25, 25}, - }, - { - {24, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - }, - { - {25, 25, 25, 25}, - {25, 25, 26, 25}, - {25, 25, 25, 25}, - {26, 25, 26, 25}, - }, - { - {25, 25, 25, 26}, - {26, 25, 26, 25}, - {25, 26, 25, 26}, - {26, 25, 26, 25}, - }, - { - {25, 26, 25, 26}, - {26, 25, 26, 26}, - {25, 26, 25, 26}, - {26, 26, 26, 26}, - }, - { - {25, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 26, 26}, - }, - { - {26, 26, 26, 26}, - {26, 26, 27, 26}, - {26, 26, 26, 26}, - {27, 26, 27, 26}, - }, - { - {26, 26, 26, 27}, - {27, 26, 27, 26}, - {26, 27, 26, 27}, - {27, 26, 27, 26}, - }, - { - {26, 27, 26, 27}, - {27, 26, 27, 27}, - {26, 27, 26, 27}, - {27, 27, 27, 27}, - }, - { - {26, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 27, 27}, - }, - { - {27, 27, 27, 27}, - {27, 27, 28, 27}, - {27, 27, 27, 27}, - {28, 27, 28, 27}, - }, - { - {27, 27, 27, 28}, - {28, 27, 28, 27}, - {27, 28, 27, 28}, - {28, 27, 28, 27}, - }, - { - {27, 28, 27, 28}, - {28, 27, 28, 28}, - {27, 28, 27, 28}, - {28, 28, 28, 27}, - }, - { - {27, 28, 28, 28}, - {28, 28, 28, 28}, - {28, 28, 27, 28}, - {28, 28, 28, 28}, - }, - { - {28, 28, 28, 28}, - {28, 28, 29, 28}, - {28, 28, 28, 28}, - {29, 28, 28, 28}, - }, - { - {28, 28, 28, 29}, - {29, 28, 29, 28}, - {28, 29, 28, 28}, - {29, 28, 29, 28}, - }, - { - {28, 29, 28, 29}, - {29, 28, 29, 29}, - {28, 29, 28, 29}, - {29, 29, 29, 28}, - }, - { - {28, 29, 29, 29}, - {29, 29, 29, 29}, - {29, 29, 28, 29}, - {29, 29, 29, 29}, - }, - { - {29, 29, 29, 29}, - {29, 29, 30, 29}, - {29, 29, 29, 29}, - {30, 29, 29, 29}, - }, - { - {29, 29, 29, 30}, - {30, 29, 30, 29}, - {29, 30, 29, 29}, - {30, 29, 30, 29}, - }, - { - {29, 30, 29, 30}, - {30, 29, 30, 30}, - {29, 30, 29, 30}, - {30, 30, 30, 29}, - }, - { - {29, 30, 30, 30}, - {30, 30, 30, 30}, - {30, 30, 29, 30}, - {30, 30, 30, 30}, - }, - { - {30, 30, 30, 30}, - {30, 30, 31, 30}, - {30, 30, 30, 30}, - {31, 30, 30, 30}, - }, - { - {30, 30, 30, 31}, - {31, 30, 31, 30}, - {30, 31, 30, 30}, - {31, 30, 31, 30}, - }, - { - {30, 31, 30, 31}, - {31, 30, 31, 31}, - {30, 31, 30, 31}, - {31, 31, 31, 30}, - }, - { - {30, 31, 31, 31}, - {31, 31, 31, 31}, - {31, 31, 30, 31}, - {31, 31, 31, 31}, - }, - { - {31, 31, 31, 31}, - {31, 31, 32, 31}, - {31, 31, 31, 31}, - {32, 31, 31, 31}, - }, - { - {31, 31, 31, 32}, - {32, 31, 32, 31}, - {31, 32, 31, 31}, - {32, 31, 32, 31}, - }, - { - {31, 32, 31, 32}, - {32, 31, 32, 32}, - {31, 32, 31, 32}, - {32, 32, 32, 31}, - }, - { - {31, 32, 32, 32}, - {32, 32, 32, 32}, - {32, 32, 31, 32}, - {32, 32, 32, 32}, - }, - { - {32, 32, 32, 32}, - {32, 32, 33, 32}, - {32, 32, 32, 32}, - {33, 32, 32, 32}, - }, - { - {32, 32, 32, 33}, - {33, 32, 33, 32}, - {32, 33, 32, 32}, - {33, 32, 33, 32}, - }, - { - {32, 33, 32, 33}, - {33, 32, 33, 33}, - {32, 33, 32, 33}, - {33, 33, 33, 32}, - }, - { - {32, 33, 33, 33}, - {33, 33, 33, 33}, - {33, 33, 32, 33}, - {33, 33, 33, 33}, - }, - { - {33, 33, 33, 33}, - {33, 33, 34, 33}, - {33, 33, 33, 33}, - {34, 33, 33, 33}, - }, - { - {33, 33, 33, 34}, - {34, 33, 34, 33}, - {33, 34, 33, 33}, - {34, 33, 34, 33}, - }, - { - {33, 34, 33, 34}, - {34, 33, 34, 34}, - {33, 34, 33, 34}, - {34, 34, 34, 33}, - }, - { - {33, 34, 34, 34}, - {34, 34, 34, 34}, - {34, 34, 33, 34}, - {34, 34, 34, 34}, - }, - { - {34, 34, 34, 34}, - {34, 34, 35, 34}, - {34, 34, 34, 34}, - {35, 34, 34, 34}, - }, - { - {34, 34, 34, 35}, - {35, 34, 35, 34}, - {34, 35, 34, 34}, - {35, 34, 35, 34}, - }, - { - {34, 35, 34, 35}, - {35, 34, 35, 35}, - {34, 35, 34, 35}, - {35, 35, 35, 34}, - }, - { - {34, 35, 35, 35}, - {35, 35, 35, 35}, - {35, 35, 34, 35}, - {35, 35, 35, 35}, - }, - { - {35, 35, 35, 35}, - {35, 35, 36, 35}, - {35, 35, 35, 35}, - {36, 35, 35, 35}, - }, - { - {35, 35, 35, 36}, - {36, 35, 36, 35}, - {35, 36, 35, 35}, - {36, 35, 36, 35}, - }, - { - {35, 36, 35, 36}, - {36, 35, 36, 35}, - {35, 36, 35, 36}, - {36, 36, 36, 35}, - }, - { - {35, 36, 35, 36}, - {36, 36, 36, 36}, - {36, 36, 35, 36}, - {36, 36, 36, 36}, - }, - { - {36, 36, 36, 36}, - {36, 36, 36, 36}, - {36, 36, 36, 36}, - {37, 36, 36, 36}, - }, - { - {36, 36, 36, 36}, - {37, 36, 37, 36}, - {36, 37, 36, 36}, - {37, 36, 37, 36}, - }, - { - {36, 37, 36, 37}, - {37, 36, 37, 36}, - {36, 37, 36, 37}, - {37, 37, 37, 36}, - }, - { - {36, 37, 36, 37}, - {37, 37, 37, 37}, - {37, 37, 36, 37}, - {37, 37, 37, 37}, - }, - { - {37, 37, 37, 37}, - {37, 37, 37, 37}, - {37, 37, 37, 37}, - {38, 37, 37, 37}, - }, - { - {37, 37, 37, 37}, - {38, 37, 38, 37}, - {37, 38, 37, 37}, - {38, 37, 38, 37}, - }, - { - {37, 38, 37, 38}, - {38, 37, 38, 37}, - {37, 38, 37, 38}, - {38, 38, 38, 37}, - }, - { - {37, 38, 37, 38}, - {38, 38, 38, 38}, - {38, 38, 37, 38}, - {38, 38, 38, 38}, - }, - { - {38, 38, 38, 38}, - {38, 38, 38, 38}, - {38, 38, 38, 38}, - {39, 38, 38, 38}, - }, - { - {38, 38, 38, 38}, - {39, 38, 39, 38}, - {38, 39, 38, 38}, - {39, 38, 39, 38}, - }, - { - {38, 39, 38, 39}, - {39, 38, 39, 38}, - {38, 39, 38, 39}, - {39, 39, 39, 38}, - }, - { - {38, 39, 38, 39}, - {39, 39, 39, 39}, - {39, 39, 38, 39}, - {39, 39, 39, 39}, - }, - { - {39, 39, 39, 39}, - {39, 39, 39, 39}, - {39, 39, 39, 39}, - {40, 39, 39, 39}, - }, - { - {39, 39, 39, 39}, - {40, 39, 40, 39}, - {39, 40, 39, 39}, - {40, 39, 40, 39}, - }, - { - {39, 40, 39, 40}, - {40, 39, 40, 39}, - {39, 40, 39, 40}, - {40, 39, 40, 39}, - }, - { - {39, 40, 39, 40}, - {40, 40, 40, 40}, - {39, 40, 39, 40}, - {40, 40, 40, 40}, - }, - { - {40, 40, 40, 40}, - {40, 40, 40, 40}, - {40, 40, 40, 40}, - {40, 40, 40, 40}, - }, - { - {40, 40, 40, 40}, - {41, 40, 41, 40}, - {40, 40, 40, 40}, - {41, 40, 41, 40}, - }, - { - {40, 41, 40, 41}, - {41, 40, 41, 40}, - {40, 41, 40, 41}, - {41, 40, 41, 40}, - }, - { - {40, 41, 40, 41}, - {41, 41, 41, 41}, - {40, 41, 40, 41}, - {41, 41, 41, 41}, - }, - { - {41, 41, 41, 41}, - {41, 41, 41, 41}, - {41, 41, 41, 41}, - {41, 41, 41, 41}, - }, - { - {41, 41, 41, 41}, - {42, 41, 42, 41}, - {41, 41, 41, 41}, - {42, 41, 42, 41}, - }, - { - {41, 42, 41, 42}, - {42, 41, 42, 41}, - {41, 42, 41, 42}, - {42, 41, 42, 41}, - }, - { - {41, 42, 41, 42}, - {42, 42, 42, 42}, - {41, 42, 41, 42}, - {42, 42, 42, 42}, - }, - { - {42, 42, 42, 42}, - {42, 42, 42, 42}, - {42, 42, 42, 42}, - {42, 42, 42, 42}, - }, - { - {42, 42, 42, 42}, - {43, 42, 43, 42}, - {42, 42, 42, 42}, - {43, 42, 43, 42}, - }, - { - {42, 43, 42, 43}, - {43, 42, 43, 42}, - {42, 43, 42, 43}, - {43, 42, 43, 42}, - }, - { - {42, 43, 42, 43}, - {43, 43, 43, 43}, - {42, 43, 42, 43}, - {43, 43, 43, 43}, - }, - { - {43, 43, 43, 43}, - {43, 43, 43, 43}, - {43, 43, 43, 43}, - {43, 43, 43, 43}, - }, - { - {43, 43, 43, 43}, - {44, 43, 44, 43}, - {43, 43, 43, 43}, - {44, 43, 44, 43}, - }, - { - {43, 43, 43, 44}, - {44, 43, 44, 43}, - {43, 44, 43, 44}, - {44, 43, 44, 43}, - }, - { - {43, 44, 43, 44}, - {44, 43, 44, 44}, - {43, 44, 43, 44}, - {44, 44, 44, 44}, - }, - { - {43, 44, 44, 44}, - {44, 44, 44, 44}, - {44, 44, 44, 44}, - {44, 44, 44, 44}, - }, - { - {44, 44, 44, 44}, - {44, 44, 45, 44}, - {44, 44, 44, 44}, - {45, 44, 45, 44}, - }, - { - {44, 44, 44, 45}, - {45, 44, 45, 44}, - {44, 45, 44, 45}, - {45, 44, 45, 44}, - }, - { - {44, 45, 44, 45}, - {45, 44, 45, 45}, - {44, 45, 44, 45}, - {45, 45, 45, 45}, - }, - { - {44, 45, 45, 45}, - {45, 45, 45, 45}, - {45, 45, 45, 45}, - {45, 45, 45, 45}, - }, - { - {45, 45, 45, 45}, - {45, 45, 46, 45}, - {45, 45, 45, 45}, - {46, 45, 46, 45}, - }, - { - {45, 45, 45, 46}, - {46, 45, 46, 45}, - {45, 46, 45, 46}, - {46, 45, 46, 45}, - }, - { - {45, 46, 45, 46}, - {46, 45, 46, 46}, - {45, 46, 45, 46}, - {46, 46, 46, 46}, - }, - { - {45, 46, 46, 46}, - {46, 46, 46, 46}, - {46, 46, 46, 46}, - {46, 46, 46, 46}, - }, - { - {46, 46, 46, 46}, - {46, 46, 47, 46}, - {46, 46, 46, 46}, - {47, 46, 47, 46}, - }, - { - {46, 46, 46, 47}, - {47, 46, 47, 46}, - {46, 47, 46, 47}, - {47, 46, 47, 46}, - }, - { - {46, 47, 46, 47}, - {47, 46, 47, 47}, - {46, 47, 46, 47}, - {47, 47, 47, 47}, - }, - { - {46, 47, 47, 47}, - {47, 47, 47, 47}, - {47, 47, 47, 47}, - {47, 47, 47, 47}, - }, - { - {47, 47, 47, 47}, - {47, 47, 48, 47}, - {47, 47, 47, 47}, - {48, 47, 48, 47}, - }, - { - {47, 47, 47, 48}, - {48, 47, 48, 47}, - {47, 48, 47, 48}, - {48, 47, 48, 47}, - }, - { - {47, 48, 47, 48}, - {48, 47, 48, 48}, - {47, 48, 47, 48}, - {48, 48, 48, 48}, - }, - { - {47, 48, 48, 48}, - {48, 48, 48, 48}, - {48, 48, 48, 48}, - {48, 48, 48, 48}, - }, - { - {48, 48, 48, 48}, - {48, 48, 49, 48}, - {48, 48, 48, 48}, - {49, 48, 49, 48}, - }, - { - {48, 48, 48, 49}, - {49, 48, 49, 48}, - {48, 49, 48, 49}, - {49, 48, 49, 48}, - }, - { - {48, 49, 48, 49}, - {49, 48, 49, 49}, - {48, 49, 48, 49}, - {49, 49, 49, 49}, - }, - { - {48, 49, 49, 49}, - {49, 49, 49, 49}, - {49, 49, 49, 49}, - {49, 49, 49, 49}, - }, - { - {49, 49, 49, 49}, - {49, 49, 50, 49}, - {49, 49, 49, 49}, - {50, 49, 50, 49}, - }, - { - {49, 49, 49, 50}, - {50, 49, 50, 49}, - {49, 50, 49, 50}, - {50, 49, 50, 49}, - }, - { - {49, 50, 49, 50}, - {50, 49, 50, 50}, - {49, 50, 49, 50}, - {50, 50, 50, 50}, - }, - { - {49, 50, 50, 50}, - {50, 50, 50, 50}, - {50, 50, 50, 50}, - {50, 50, 50, 50}, - }, - { - {50, 50, 50, 50}, - {50, 50, 51, 50}, - {50, 50, 50, 50}, - {51, 50, 51, 50}, - }, - { - {50, 50, 50, 51}, - {51, 50, 51, 50}, - {50, 51, 50, 51}, - {51, 50, 51, 50}, - }, - { - {50, 51, 50, 51}, - {51, 50, 51, 51}, - {50, 51, 50, 51}, - {51, 51, 51, 51}, - }, - { - {50, 51, 51, 51}, - {51, 51, 51, 51}, - {51, 51, 51, 51}, - {51, 51, 51, 51}, - }, - { - {51, 51, 51, 51}, - {51, 51, 52, 51}, - {51, 51, 51, 51}, - {52, 51, 52, 51}, - }, - { - {51, 51, 51, 52}, - {52, 51, 52, 51}, - {51, 52, 51, 51}, - {52, 51, 52, 51}, - }, - { - {51, 52, 51, 52}, - {52, 51, 52, 52}, - {51, 52, 51, 52}, - {52, 52, 52, 51}, - }, - { - {51, 52, 52, 52}, - {52, 52, 52, 52}, - {52, 52, 51, 52}, - {52, 52, 52, 52}, - }, - { - {52, 52, 52, 52}, - {52, 52, 53, 52}, - {52, 52, 52, 52}, - {53, 52, 52, 52}, - }, - { - {52, 52, 52, 53}, - {53, 52, 53, 52}, - {52, 53, 52, 52}, - {53, 52, 53, 52}, - }, - { - {52, 53, 52, 53}, - {53, 52, 53, 53}, - {52, 53, 52, 53}, - {53, 53, 53, 52}, - }, - { - {52, 53, 53, 53}, - {53, 53, 53, 53}, - {53, 53, 52, 53}, - {53, 53, 53, 53}, - }, - { - {53, 53, 53, 53}, - {53, 53, 54, 53}, - {53, 53, 53, 53}, - {54, 53, 53, 53}, - }, - { - {53, 53, 53, 54}, - {54, 53, 54, 53}, - {53, 54, 53, 53}, - {54, 53, 54, 53}, - }, - { - {53, 54, 53, 54}, - {54, 53, 54, 54}, - {53, 54, 53, 54}, - {54, 54, 54, 53}, - }, - { - {53, 54, 54, 54}, - {54, 54, 54, 54}, - {54, 54, 53, 54}, - {54, 54, 54, 54}, - }, - { - {54, 54, 54, 54}, - {54, 54, 55, 54}, - {54, 54, 54, 54}, - {55, 54, 54, 54}, - }, - { - {54, 54, 54, 55}, - {55, 54, 55, 54}, - {54, 55, 54, 54}, - {55, 54, 55, 54}, - }, - { - {54, 55, 54, 55}, - {55, 54, 55, 55}, - {54, 55, 54, 55}, - {55, 55, 55, 54}, - }, - { - {54, 55, 55, 55}, - {55, 55, 55, 55}, - {55, 55, 54, 55}, - {55, 55, 55, 55}, - }, - { - {55, 55, 55, 55}, - {55, 55, 56, 55}, - {55, 55, 55, 55}, - {56, 55, 55, 55}, - }, - { - {55, 55, 55, 55}, - {56, 55, 56, 55}, - {55, 56, 55, 55}, - {56, 55, 56, 55}, - }, - { - {55, 56, 55, 56}, - {56, 55, 56, 55}, - {55, 56, 55, 56}, - {56, 56, 56, 55}, - }, - { - {55, 56, 55, 56}, - {56, 56, 56, 56}, - {56, 56, 55, 56}, - {56, 56, 56, 56}, - }, - { - {56, 56, 56, 56}, - {56, 56, 56, 56}, - {56, 56, 56, 56}, - {57, 56, 56, 56}, - }, - { - {56, 56, 56, 56}, - {57, 56, 57, 56}, - {56, 57, 56, 56}, - {57, 56, 57, 56}, - }, - { - {56, 57, 56, 57}, - {57, 56, 57, 56}, - {56, 57, 56, 57}, - {57, 57, 57, 56}, - }, - { - {56, 57, 56, 57}, - {57, 57, 57, 57}, - {57, 57, 56, 57}, - {57, 57, 57, 57}, - }, - { - {57, 57, 57, 57}, - {57, 57, 57, 57}, - {57, 57, 57, 57}, - {58, 57, 57, 57}, - }, - { - {57, 57, 57, 57}, - {58, 57, 58, 57}, - {57, 58, 57, 57}, - {58, 57, 58, 57}, - }, - { - {57, 58, 57, 58}, - {58, 57, 58, 57}, - {57, 58, 57, 58}, - {58, 58, 58, 57}, - }, - { - {57, 58, 57, 58}, - {58, 58, 58, 58}, - {58, 58, 57, 58}, - {58, 58, 58, 58}, - }, - { - {58, 58, 58, 58}, - {58, 58, 58, 58}, - {58, 58, 58, 58}, - {59, 58, 58, 58}, - }, - { - {58, 58, 58, 58}, - {59, 58, 59, 58}, - {58, 59, 58, 58}, - {59, 58, 59, 58}, - }, - { - {58, 59, 58, 59}, - {59, 58, 59, 58}, - {58, 59, 58, 59}, - {59, 59, 59, 58}, - }, - { - {58, 59, 58, 59}, - {59, 59, 59, 59}, - {59, 59, 58, 59}, - {59, 59, 59, 59}, - }, - { - {59, 59, 59, 59}, - {59, 59, 59, 59}, - {59, 59, 59, 59}, - {60, 59, 59, 59}, - }, - { - {59, 59, 59, 59}, - {60, 59, 60, 59}, - {59, 59, 59, 59}, - {60, 59, 60, 59}, - }, - { - {59, 60, 59, 60}, - {60, 59, 60, 59}, - {59, 60, 59, 60}, - {60, 59, 60, 59}, - }, - { - {59, 60, 59, 60}, - {60, 60, 60, 60}, - {59, 60, 59, 60}, - {60, 60, 60, 60}, - }, - { - {60, 60, 60, 60}, - {60, 60, 60, 60}, - {60, 60, 60, 60}, - {60, 60, 60, 60}, - }, - { - {60, 60, 60, 60}, - {61, 60, 61, 60}, - {60, 60, 60, 60}, - {61, 60, 61, 60}, - }, - { - {60, 61, 60, 61}, - {61, 60, 61, 60}, - {60, 61, 60, 61}, - {61, 60, 61, 60}, - }, - { - {60, 61, 60, 61}, - {61, 61, 61, 61}, - {60, 61, 60, 61}, - {61, 61, 61, 61}, - }, - { - {61, 61, 61, 61}, - {61, 61, 61, 61}, - {61, 61, 61, 61}, - {61, 61, 61, 61}, - }, - { - {61, 61, 61, 61}, - {62, 61, 62, 61}, - {61, 61, 61, 61}, - {62, 61, 62, 61}, - }, - { - {61, 62, 61, 62}, - {62, 61, 62, 61}, - {61, 62, 61, 62}, - {62, 61, 62, 61}, - }, - { - {61, 62, 61, 62}, - {62, 62, 62, 62}, - {61, 62, 61, 62}, - {62, 62, 62, 62}, - }, - { - {62, 62, 62, 62}, - {62, 62, 62, 62}, - {62, 62, 62, 62}, - {62, 62, 62, 62}, - }, - { - {62, 62, 62, 62}, - {63, 62, 63, 62}, - {62, 62, 62, 62}, - {63, 62, 63, 62}, - }, - { - {62, 63, 62, 63}, - {63, 62, 63, 62}, - {62, 63, 62, 63}, - {63, 62, 63, 62}, - }, - { - {62, 63, 62, 63}, - {63, 63, 63, 63}, - {62, 63, 62, 63}, - {63, 63, 63, 63}, - }, - { - {63, 63, 63, 63}, - {63, 63, 63, 63}, - {63, 63, 63, 63}, - {63, 63, 63, 63}, - }, -}; - -uint8_t dither_rb2x2[256][2][2] = -{ - { - {0, 0}, - {0, 0}, - }, - { - {0, 0}, - {1, 0}, - }, - { - {0, 0}, - {1, 0}, - }, - { - {0, 1}, - {1, 0}, - }, - { - {0, 1}, - {1, 0}, - }, - { - {0, 1}, - {1, 1}, - }, - { - {0, 1}, - {1, 1}, - }, - { - {1, 1}, - {1, 1}, - }, - { - {1, 1}, - {1, 1}, - }, - { - {1, 1}, - {2, 1}, - }, - { - {1, 1}, - {2, 1}, - }, - { - {1, 2}, - {2, 1}, - }, - { - {1, 2}, - {2, 1}, - }, - { - {1, 2}, - {2, 2}, - }, - { - {1, 2}, - {2, 2}, - }, - { - {2, 2}, - {2, 2}, - }, - { - {2, 2}, - {2, 2}, - }, - { - {2, 2}, - {2, 2}, - }, - { - {2, 2}, - {3, 2}, - }, - { - {2, 2}, - {3, 2}, - }, - { - {2, 3}, - {3, 2}, - }, - { - {2, 3}, - {3, 2}, - }, - { - {2, 3}, - {3, 3}, - }, - { - {2, 3}, - {3, 3}, - }, - { - {3, 3}, - {3, 3}, - }, - { - {3, 3}, - {3, 3}, - }, - { - {3, 3}, - {4, 3}, - }, - { - {3, 3}, - {4, 3}, - }, - { - {3, 4}, - {4, 3}, - }, - { - {3, 4}, - {4, 3}, - }, - { - {3, 4}, - {4, 4}, - }, - { - {3, 4}, - {4, 4}, - }, - { - {4, 4}, - {4, 4}, - }, - { - {4, 4}, - {4, 4}, - }, - { - {4, 4}, - {5, 4}, - }, - { - {4, 4}, - {5, 4}, - }, - { - {4, 5}, - {5, 4}, - }, - { - {4, 5}, - {5, 4}, - }, - { - {4, 5}, - {5, 5}, - }, - { - {4, 5}, - {5, 5}, - }, - { - {5, 5}, - {5, 5}, - }, - { - {5, 5}, - {5, 5}, - }, - { - {5, 5}, - {6, 5}, - }, - { - {5, 5}, - {6, 5}, - }, - { - {5, 6}, - {6, 5}, - }, - { - {5, 6}, - {6, 5}, - }, - { - {5, 6}, - {6, 6}, - }, - { - {5, 6}, - {6, 6}, - }, - { - {5, 6}, - {6, 6}, - }, - { - {6, 6}, - {6, 6}, - }, - { - {6, 6}, - {6, 6}, - }, - { - {6, 6}, - {7, 6}, - }, - { - {6, 6}, - {7, 6}, - }, - { - {6, 7}, - {7, 6}, - }, - { - {6, 7}, - {7, 6}, - }, - { - {6, 7}, - {7, 7}, - }, - { - {6, 7}, - {7, 7}, - }, - { - {7, 7}, - {7, 7}, - }, - { - {7, 7}, - {7, 7}, - }, - { - {7, 7}, - {8, 7}, - }, - { - {7, 7}, - {8, 7}, - }, - { - {7, 8}, - {8, 7}, - }, - { - {7, 8}, - {8, 7}, - }, - { - {7, 8}, - {8, 8}, - }, - { - {7, 8}, - {8, 8}, - }, - { - {8, 8}, - {8, 8}, - }, - { - {8, 8}, - {8, 8}, - }, - { - {8, 8}, - {9, 8}, - }, - { - {8, 8}, - {9, 8}, - }, - { - {8, 9}, - {9, 8}, - }, - { - {8, 9}, - {9, 8}, - }, - { - {8, 9}, - {9, 9}, - }, - { - {8, 9}, - {9, 9}, - }, - { - {9, 9}, - {9, 9}, - }, - { - {9, 9}, - {9, 9}, - }, - { - {9, 9}, - {10, 9}, - }, - { - {9, 9}, - {10, 9}, - }, - { - {9, 10}, - {10, 9}, - }, - { - {9, 10}, - {10, 9}, - }, - { - {9, 10}, - {10, 10}, - }, - { - {9, 10}, - {10, 10}, - }, - { - {9, 10}, - {10, 10}, - }, - { - {10, 10}, - {10, 10}, - }, - { - {10, 10}, - {10, 10}, - }, - { - {10, 10}, - {11, 10}, - }, - { - {10, 10}, - {11, 10}, - }, - { - {10, 11}, - {11, 10}, - }, - { - {10, 11}, - {11, 10}, - }, - { - {10, 11}, - {11, 11}, - }, - { - {10, 11}, - {11, 11}, - }, - { - {11, 11}, - {11, 11}, - }, - { - {11, 11}, - {11, 11}, - }, - { - {11, 11}, - {12, 11}, - }, - { - {11, 11}, - {12, 11}, - }, - { - {11, 12}, - {12, 11}, - }, - { - {11, 12}, - {12, 11}, - }, - { - {11, 12}, - {12, 12}, - }, - { - {11, 12}, - {12, 12}, - }, - { - {12, 12}, - {12, 12}, - }, - { - {12, 12}, - {12, 12}, - }, - { - {12, 12}, - {13, 12}, - }, - { - {12, 12}, - {13, 12}, - }, - { - {12, 13}, - {13, 12}, - }, - { - {12, 13}, - {13, 12}, - }, - { - {12, 13}, - {13, 13}, - }, - { - {12, 13}, - {13, 13}, - }, - { - {13, 13}, - {13, 13}, - }, - { - {13, 13}, - {13, 13}, - }, - { - {13, 13}, - {14, 13}, - }, - { - {13, 13}, - {14, 13}, - }, - { - {13, 14}, - {14, 13}, - }, - { - {13, 14}, - {14, 13}, - }, - { - {13, 14}, - {14, 13}, - }, - { - {13, 14}, - {14, 14}, - }, - { - {13, 14}, - {14, 14}, - }, - { - {14, 14}, - {14, 14}, - }, - { - {14, 14}, - {14, 14}, - }, - { - {14, 14}, - {15, 14}, - }, - { - {14, 14}, - {15, 14}, - }, - { - {14, 15}, - {15, 14}, - }, - { - {14, 15}, - {15, 14}, - }, - { - {14, 15}, - {15, 15}, - }, - { - {14, 15}, - {15, 15}, - }, - { - {15, 15}, - {15, 15}, - }, - { - {15, 15}, - {15, 15}, - }, - { - {15, 15}, - {16, 15}, - }, - { - {15, 15}, - {16, 15}, - }, - { - {15, 16}, - {16, 15}, - }, - { - {15, 16}, - {16, 15}, - }, - { - {15, 16}, - {16, 16}, - }, - { - {15, 16}, - {16, 16}, - }, - { - {16, 16}, - {16, 16}, - }, - { - {16, 16}, - {16, 16}, - }, - { - {16, 16}, - {17, 16}, - }, - { - {16, 16}, - {17, 16}, - }, - { - {16, 17}, - {17, 16}, - }, - { - {16, 17}, - {17, 16}, - }, - { - {16, 17}, - {17, 17}, - }, - { - {16, 17}, - {17, 17}, - }, - { - {17, 17}, - {17, 17}, - }, - { - {17, 17}, - {17, 17}, - }, - { - {17, 17}, - {18, 17}, - }, - { - {17, 17}, - {18, 17}, - }, - { - {17, 18}, - {18, 17}, - }, - { - {17, 18}, - {18, 17}, - }, - { - {17, 18}, - {18, 18}, - }, - { - {17, 18}, - {18, 18}, - }, - { - {18, 18}, - {18, 18}, - }, - { - {18, 18}, - {18, 18}, - }, - { - {18, 18}, - {19, 18}, - }, - { - {18, 18}, - {19, 18}, - }, - { - {18, 19}, - {19, 18}, - }, - { - {18, 19}, - {19, 18}, - }, - { - {18, 19}, - {19, 19}, - }, - { - {18, 19}, - {19, 19}, - }, - { - {19, 19}, - {19, 19}, - }, - { - {19, 19}, - {19, 19}, - }, - { - {19, 19}, - {20, 19}, - }, - { - {19, 19}, - {20, 19}, - }, - { - {19, 20}, - {20, 19}, - }, - { - {19, 20}, - {20, 19}, - }, - { - {19, 20}, - {20, 19}, - }, - { - {19, 20}, - {20, 20}, - }, - { - {19, 20}, - {20, 20}, - }, - { - {20, 20}, - {20, 20}, - }, - { - {20, 20}, - {20, 20}, - }, - { - {20, 20}, - {21, 20}, - }, - { - {20, 20}, - {21, 20}, - }, - { - {20, 21}, - {21, 20}, - }, - { - {20, 21}, - {21, 20}, - }, - { - {20, 21}, - {21, 21}, - }, - { - {20, 21}, - {21, 21}, - }, - { - {21, 21}, - {21, 21}, - }, - { - {21, 21}, - {21, 21}, - }, - { - {21, 21}, - {22, 21}, - }, - { - {21, 21}, - {22, 21}, - }, - { - {21, 22}, - {22, 21}, - }, - { - {21, 22}, - {22, 21}, - }, - { - {21, 22}, - {22, 22}, - }, - { - {21, 22}, - {22, 22}, - }, - { - {22, 22}, - {22, 22}, - }, - { - {22, 22}, - {22, 22}, - }, - { - {22, 22}, - {23, 22}, - }, - { - {22, 22}, - {23, 22}, - }, - { - {22, 23}, - {23, 22}, - }, - { - {22, 23}, - {23, 22}, - }, - { - {22, 23}, - {23, 23}, - }, - { - {22, 23}, - {23, 23}, - }, - { - {23, 23}, - {23, 23}, - }, - { - {23, 23}, - {23, 23}, - }, - { - {23, 23}, - {24, 23}, - }, - { - {23, 23}, - {24, 23}, - }, - { - {23, 23}, - {24, 23}, - }, - { - {23, 24}, - {24, 23}, - }, - { - {23, 24}, - {24, 23}, - }, - { - {23, 24}, - {24, 24}, - }, - { - {23, 24}, - {24, 24}, - }, - { - {24, 24}, - {24, 24}, - }, - { - {24, 24}, - {24, 24}, - }, - { - {24, 24}, - {25, 24}, - }, - { - {24, 24}, - {25, 24}, - }, - { - {24, 25}, - {25, 24}, - }, - { - {24, 25}, - {25, 24}, - }, - { - {24, 25}, - {25, 25}, - }, - { - {24, 25}, - {25, 25}, - }, - { - {25, 25}, - {25, 25}, - }, - { - {25, 25}, - {25, 25}, - }, - { - {25, 25}, - {26, 25}, - }, - { - {25, 25}, - {26, 25}, - }, - { - {25, 26}, - {26, 25}, - }, - { - {25, 26}, - {26, 25}, - }, - { - {25, 26}, - {26, 26}, - }, - { - {25, 26}, - {26, 26}, - }, - { - {26, 26}, - {26, 26}, - }, - { - {26, 26}, - {26, 26}, - }, - { - {26, 26}, - {27, 26}, - }, - { - {26, 26}, - {27, 26}, - }, - { - {26, 27}, - {27, 26}, - }, - { - {26, 27}, - {27, 26}, - }, - { - {26, 27}, - {27, 27}, - }, - { - {26, 27}, - {27, 27}, - }, - { - {27, 27}, - {27, 27}, - }, - { - {27, 27}, - {27, 27}, - }, - { - {27, 27}, - {28, 27}, - }, - { - {27, 27}, - {28, 27}, - }, - { - {27, 27}, - {28, 27}, - }, - { - {27, 28}, - {28, 27}, - }, - { - {27, 28}, - {28, 27}, - }, - { - {27, 28}, - {28, 28}, - }, - { - {27, 28}, - {28, 28}, - }, - { - {28, 28}, - {28, 28}, - }, - { - {28, 28}, - {28, 28}, - }, - { - {28, 28}, - {29, 28}, - }, - { - {28, 28}, - {29, 28}, - }, - { - {28, 29}, - {29, 28}, - }, - { - {28, 29}, - {29, 28}, - }, - { - {28, 29}, - {29, 29}, - }, - { - {28, 29}, - {29, 29}, - }, - { - {29, 29}, - {29, 29}, - }, - { - {29, 29}, - {29, 29}, - }, - { - {29, 29}, - {30, 29}, - }, - { - {29, 29}, - {30, 29}, - }, - { - {29, 30}, - {30, 29}, - }, - { - {29, 30}, - {30, 29}, - }, - { - {29, 30}, - {30, 30}, - }, - { - {29, 30}, - {30, 30}, - }, - { - {30, 30}, - {30, 30}, - }, - { - {30, 30}, - {30, 30}, - }, - { - {30, 30}, - {31, 30}, - }, - { - {30, 30}, - {31, 30}, - }, - { - {30, 31}, - {31, 30}, - }, - { - {30, 31}, - {31, 30}, - }, - { - {30, 31}, - {31, 31}, - }, - { - {30, 31}, - {31, 31}, - }, - { - {31, 31}, - {31, 31}, - }, - { - {31, 31}, - {31, 31}, - }, -}; - -uint8_t dither_g2x2[256][2][2] = -{ - { - {0, 0}, - {0, 0}, - }, - { - {0, 0}, - {1, 0}, - }, - { - {0, 1}, - {1, 0}, - }, - { - {0, 1}, - {1, 1}, - }, - { - {1, 1}, - {1, 1}, - }, - { - {1, 1}, - {2, 1}, - }, - { - {1, 2}, - {2, 1}, - }, - { - {1, 2}, - {2, 2}, - }, - { - {2, 2}, - {2, 2}, - }, - { - {2, 2}, - {3, 2}, - }, - { - {2, 3}, - {3, 2}, - }, - { - {2, 3}, - {3, 3}, - }, - { - {3, 3}, - {3, 3}, - }, - { - {3, 3}, - {4, 3}, - }, - { - {3, 4}, - {4, 3}, - }, - { - {3, 4}, - {4, 4}, - }, - { - {4, 4}, - {4, 4}, - }, - { - {4, 4}, - {5, 4}, - }, - { - {4, 5}, - {5, 4}, - }, - { - {4, 5}, - {5, 5}, - }, - { - {5, 5}, - {5, 5}, - }, - { - {5, 5}, - {6, 5}, - }, - { - {5, 6}, - {6, 5}, - }, - { - {5, 6}, - {6, 6}, - }, - { - {6, 6}, - {6, 6}, - }, - { - {6, 6}, - {7, 6}, - }, - { - {6, 7}, - {7, 6}, - }, - { - {6, 7}, - {7, 7}, - }, - { - {7, 7}, - {7, 7}, - }, - { - {7, 7}, - {8, 7}, - }, - { - {7, 8}, - {8, 7}, - }, - { - {7, 8}, - {8, 8}, - }, - { - {8, 8}, - {8, 8}, - }, - { - {8, 8}, - {9, 8}, - }, - { - {8, 9}, - {9, 8}, - }, - { - {8, 9}, - {9, 9}, - }, - { - {9, 9}, - {9, 9}, - }, - { - {9, 9}, - {10, 9}, - }, - { - {9, 10}, - {10, 9}, - }, - { - {9, 10}, - {10, 10}, - }, - { - {10, 10}, - {10, 10}, - }, - { - {10, 10}, - {11, 10}, - }, - { - {10, 11}, - {11, 10}, - }, - { - {10, 11}, - {11, 11}, - }, - { - {11, 11}, - {11, 11}, - }, - { - {11, 11}, - {12, 11}, - }, - { - {11, 12}, - {12, 11}, - }, - { - {11, 12}, - {12, 12}, - }, - { - {11, 12}, - {12, 12}, - }, - { - {12, 12}, - {12, 12}, - }, - { - {12, 12}, - {13, 12}, - }, - { - {12, 13}, - {13, 12}, - }, - { - {12, 13}, - {13, 13}, - }, - { - {13, 13}, - {13, 13}, - }, - { - {13, 13}, - {14, 13}, - }, - { - {13, 14}, - {14, 13}, - }, - { - {13, 14}, - {14, 14}, - }, - { - {14, 14}, - {14, 14}, - }, - { - {14, 14}, - {15, 14}, - }, - { - {14, 15}, - {15, 14}, - }, - { - {14, 15}, - {15, 15}, - }, - { - {15, 15}, - {15, 15}, - }, - { - {15, 15}, - {16, 15}, - }, - { - {15, 16}, - {16, 15}, - }, - { - {15, 16}, - {16, 16}, - }, - { - {16, 16}, - {16, 16}, - }, - { - {16, 16}, - {17, 16}, - }, - { - {16, 17}, - {17, 16}, - }, - { - {16, 17}, - {17, 17}, - }, - { - {17, 17}, - {17, 17}, - }, - { - {17, 17}, - {18, 17}, - }, - { - {17, 18}, - {18, 17}, - }, - { - {17, 18}, - {18, 18}, - }, - { - {18, 18}, - {18, 18}, - }, - { - {18, 18}, - {19, 18}, - }, - { - {18, 19}, - {19, 18}, - }, - { - {18, 19}, - {19, 19}, - }, - { - {19, 19}, - {19, 19}, - }, - { - {19, 19}, - {20, 19}, - }, - { - {19, 20}, - {20, 19}, - }, - { - {19, 20}, - {20, 20}, - }, - { - {20, 20}, - {20, 20}, - }, - { - {20, 20}, - {21, 20}, - }, - { - {20, 21}, - {21, 20}, - }, - { - {20, 21}, - {21, 21}, - }, - { - {21, 21}, - {21, 21}, - }, - { - {21, 21}, - {22, 21}, - }, - { - {21, 22}, - {22, 21}, - }, - { - {21, 22}, - {22, 22}, - }, - { - {22, 22}, - {22, 22}, - }, - { - {22, 22}, - {23, 22}, - }, - { - {22, 23}, - {23, 22}, - }, - { - {22, 23}, - {23, 23}, - }, - { - {23, 23}, - {23, 23}, - }, - { - {23, 23}, - {24, 23}, - }, - { - {23, 24}, - {24, 23}, - }, - { - {23, 24}, - {24, 24}, - }, - { - {24, 24}, - {24, 24}, - }, - { - {24, 24}, - {25, 24}, - }, - { - {24, 25}, - {25, 24}, - }, - { - {24, 25}, - {25, 25}, - }, - { - {25, 25}, - {25, 25}, - }, - { - {25, 25}, - {26, 25}, - }, - { - {25, 26}, - {26, 25}, - }, - { - {25, 26}, - {26, 26}, - }, - { - {26, 26}, - {26, 26}, - }, - { - {26, 26}, - {27, 26}, - }, - { - {26, 27}, - {27, 26}, - }, - { - {26, 27}, - {27, 27}, - }, - { - {27, 27}, - {27, 27}, - }, - { - {27, 27}, - {28, 27}, - }, - { - {27, 28}, - {28, 27}, - }, - { - {27, 28}, - {28, 28}, - }, - { - {28, 28}, - {28, 28}, - }, - { - {28, 28}, - {29, 28}, - }, - { - {28, 29}, - {29, 28}, - }, - { - {28, 29}, - {29, 29}, - }, - { - {29, 29}, - {29, 29}, - }, - { - {29, 29}, - {30, 29}, - }, - { - {29, 30}, - {30, 29}, - }, - { - {29, 30}, - {30, 30}, - }, - { - {30, 30}, - {30, 30}, - }, - { - {30, 30}, - {31, 30}, - }, - { - {30, 31}, - {31, 30}, - }, - { - {30, 31}, - {31, 31}, - }, - { - {31, 31}, - {31, 31}, - }, - { - {31, 31}, - {32, 31}, - }, - { - {31, 32}, - {32, 31}, - }, - { - {31, 32}, - {32, 32}, - }, - { - {32, 32}, - {32, 32}, - }, - { - {32, 32}, - {33, 32}, - }, - { - {32, 33}, - {33, 32}, - }, - { - {32, 33}, - {33, 33}, - }, - { - {33, 33}, - {33, 33}, - }, - { - {33, 33}, - {34, 33}, - }, - { - {33, 34}, - {34, 33}, - }, - { - {33, 34}, - {34, 34}, - }, - { - {34, 34}, - {34, 34}, - }, - { - {34, 34}, - {35, 34}, - }, - { - {34, 35}, - {35, 34}, - }, - { - {34, 35}, - {35, 35}, - }, - { - {35, 35}, - {35, 35}, - }, - { - {35, 35}, - {36, 35}, - }, - { - {35, 36}, - {36, 35}, - }, - { - {35, 36}, - {36, 35}, - }, - { - {35, 36}, - {36, 36}, - }, - { - {36, 36}, - {36, 36}, - }, - { - {36, 36}, - {37, 36}, - }, - { - {36, 37}, - {37, 36}, - }, - { - {36, 37}, - {37, 37}, - }, - { - {37, 37}, - {37, 37}, - }, - { - {37, 37}, - {38, 37}, - }, - { - {37, 38}, - {38, 37}, - }, - { - {37, 38}, - {38, 38}, - }, - { - {38, 38}, - {38, 38}, - }, - { - {38, 38}, - {39, 38}, - }, - { - {38, 39}, - {39, 38}, - }, - { - {38, 39}, - {39, 39}, - }, - { - {39, 39}, - {39, 39}, - }, - { - {39, 39}, - {40, 39}, - }, - { - {39, 40}, - {40, 39}, - }, - { - {39, 40}, - {40, 40}, - }, - { - {40, 40}, - {40, 40}, - }, - { - {40, 40}, - {41, 40}, - }, - { - {40, 41}, - {41, 40}, - }, - { - {40, 41}, - {41, 41}, - }, - { - {41, 41}, - {41, 41}, - }, - { - {41, 41}, - {42, 41}, - }, - { - {41, 42}, - {42, 41}, - }, - { - {41, 42}, - {42, 42}, - }, - { - {42, 42}, - {42, 42}, - }, - { - {42, 42}, - {43, 42}, - }, - { - {42, 43}, - {43, 42}, - }, - { - {42, 43}, - {43, 43}, - }, - { - {43, 43}, - {43, 43}, - }, - { - {43, 43}, - {44, 43}, - }, - { - {43, 44}, - {44, 43}, - }, - { - {43, 44}, - {44, 44}, - }, - { - {44, 44}, - {44, 44}, - }, - { - {44, 44}, - {45, 44}, - }, - { - {44, 45}, - {45, 44}, - }, - { - {44, 45}, - {45, 45}, - }, - { - {45, 45}, - {45, 45}, - }, - { - {45, 45}, - {46, 45}, - }, - { - {45, 46}, - {46, 45}, - }, - { - {45, 46}, - {46, 46}, - }, - { - {46, 46}, - {46, 46}, - }, - { - {46, 46}, - {47, 46}, - }, - { - {46, 47}, - {47, 46}, - }, - { - {46, 47}, - {47, 47}, - }, - { - {47, 47}, - {47, 47}, - }, - { - {47, 47}, - {48, 47}, - }, - { - {47, 48}, - {48, 47}, - }, - { - {47, 48}, - {48, 48}, - }, - { - {48, 48}, - {48, 48}, - }, - { - {48, 48}, - {49, 48}, - }, - { - {48, 49}, - {49, 48}, - }, - { - {48, 49}, - {49, 49}, - }, - { - {49, 49}, - {49, 49}, - }, - { - {49, 49}, - {50, 49}, - }, - { - {49, 50}, - {50, 49}, - }, - { - {49, 50}, - {50, 50}, - }, - { - {50, 50}, - {50, 50}, - }, - { - {50, 50}, - {51, 50}, - }, - { - {50, 51}, - {51, 50}, - }, - { - {50, 51}, - {51, 51}, - }, - { - {51, 51}, - {51, 51}, - }, - { - {51, 51}, - {52, 51}, - }, - { - {51, 52}, - {52, 51}, - }, - { - {51, 52}, - {52, 52}, - }, - { - {52, 52}, - {52, 52}, - }, - { - {52, 52}, - {53, 52}, - }, - { - {52, 53}, - {53, 52}, - }, - { - {52, 53}, - {53, 53}, - }, - { - {53, 53}, - {53, 53}, - }, - { - {53, 53}, - {54, 53}, - }, - { - {53, 54}, - {54, 53}, - }, - { - {53, 54}, - {54, 54}, - }, - { - {54, 54}, - {54, 54}, - }, - { - {54, 54}, - {55, 54}, - }, - { - {54, 55}, - {55, 54}, - }, - { - {54, 55}, - {55, 55}, - }, - { - {55, 55}, - {55, 55}, - }, - { - {55, 55}, - {56, 55}, - }, - { - {55, 55}, - {56, 55}, - }, - { - {55, 56}, - {56, 55}, - }, - { - {55, 56}, - {56, 56}, - }, - { - {56, 56}, - {56, 56}, - }, - { - {56, 56}, - {57, 56}, - }, - { - {56, 57}, - {57, 56}, - }, - { - {56, 57}, - {57, 57}, - }, - { - {57, 57}, - {57, 57}, - }, - { - {57, 57}, - {58, 57}, - }, - { - {57, 58}, - {58, 57}, - }, - { - {57, 58}, - {58, 58}, - }, - { - {58, 58}, - {58, 58}, - }, - { - {58, 58}, - {59, 58}, - }, - { - {58, 59}, - {59, 58}, - }, - { - {58, 59}, - {59, 59}, - }, - { - {59, 59}, - {59, 59}, - }, - { - {59, 59}, - {60, 59}, - }, - { - {59, 60}, - {60, 59}, - }, - { - {59, 60}, - {60, 60}, - }, - { - {60, 60}, - {60, 60}, - }, - { - {60, 60}, - {61, 60}, - }, - { - {60, 61}, - {61, 60}, - }, - { - {60, 61}, - {61, 61}, - }, - { - {61, 61}, - {61, 61}, - }, - { - {61, 61}, - {62, 61}, - }, - { - {61, 62}, - {62, 61}, - }, - { - {61, 62}, - {62, 62}, - }, - { - {62, 62}, - {62, 62}, - }, - { - {62, 62}, - {63, 62}, - }, - { - {62, 63}, - {63, 62}, - }, - { - {62, 63}, - {63, 63}, - }, - { - {63, 63}, - {63, 63}, - }, -}; - diff --git a/backup code/video - Cópia/vid_wy700.c b/backup code/video - Cópia/vid_wy700.c deleted file mode 100644 index 814da2cca..000000000 --- a/backup code/video - Cópia/vid_wy700.c +++ /dev/null @@ -1,1021 +0,0 @@ -/* - * 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. - * - * Wyse-700 emulation. - * - * Version: @(#)vid_wy700.c 1.0.9 2018/05/20 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../io.h" -#include "../pit.h" -#include "../mem.h" -#include "../timer.h" -#include "../device.h" -#include "video.h" -#include "vid_wy700.h" - - -#define WY700_XSIZE 1280 -#define WY700_YSIZE 800 - - -void updatewindowsize(int x, int y); - - -/* The Wyse 700 is an unusual video card. Though it has an MC6845 CRTC, this - * is not exposed directly to the host PC. Instead, the CRTC is controlled by - * an MC68705P3 microcontroller. - * - * Rather than emulate the real CRTC, I'm writing this as more or less a - * fixed-frequency card with a 1280x800 display, and scaling its selection - * of modes to that window. - * - * By default, the card responds to both the CGA and MDA I/O and memory - * ranges. Either range can be disabled by means of jumpers; this allows - * the Wy700 to coexist with a CGA or MDA. - * - * wy700->wy700_mode indicates which of the supported video modes is in use: - * - * 0x00: 40x 25 text (CGA compatible) [32x32 character cell] - * 0x02: 80x 25 text (CGA / MDA compatible) [16x32 character cell] - * 0x04: 320x200x4 graphics (CGA compatible) - * 0x06: 640x200x2 graphics (CGA compatible) - * 0x80: 640x400x2 graphics - * 0x90: 320x400x4 graphics - * 0xA0: 1280x400x2 graphics - * 0xB0: 640x400x4 graphics - * 0xC0: 1280x800x2 graphics (interleaved) - * 0xD0: 640x800x4 graphics (interleaved) - * In hi-res graphics modes, bit 3 of the mode byte is the enable flag. - * - */ - -/* What works (or appears to) : - * MDA/CGA 80x25 text mode - * CGA 40x25 text mode - * CGA 640x200 graphics mode - * CGA 320x200 graphics mode - * Hi-res graphics modes - * Font selection - * Display enable / disable - * -- via Wy700 mode register (in hi-res modes) - * -- via Wy700 command register (in text & CGA modes) - * -- via CGA/MDA control register (in text & CGA modes) - * - * What doesn't work, is untested or not well understood: - * - Cursor detach (commands 4 and 5) - */ - - -/* The microcontroller sets up the real CRTC with one of five fixed mode - * definitions. As written, this is a fairly simplistic emulation that - * doesn't attempt to closely follow the actual working of the CRTC; but I've - * included the definitions here for information. */ - -static uint8_t mode_1280x800[] = -{ - 0x31, /* Horizontal total */ - 0x28, /* Horizontal displayed */ - 0x29, /* Horizontal sync position */ - 0x06, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x03, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ -}; - -static uint8_t mode_1280x400[] = -{ - 0x31, /* Horizontal total */ - 0x28, /* Horizontal displayed */ - 0x29, /* Horizontal sync position */ - 0x06, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x01, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ -}; - -static uint8_t mode_640x400[] = -{ - 0x18, /* Horizontal total */ - 0x14, /* Horizontal displayed */ - 0x14, /* Horizontal sync position */ - 0x03, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x01, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ -}; - -static uint8_t mode_640x200[] = -{ - 0x18, /* Horizontal total */ - 0x14, /* Horizontal displayed */ - 0x14, /* Horizontal sync position */ - 0xff, /* Horizontal sync width */ - 0x37, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x32, /* Vertical displayed */ - 0x34, /* Vsync position */ - 0x03, /* Interlace and skew */ - 0x07, /* Maximum raster address */ -}; - -static uint8_t mode_80x24[] = -{ - 0x31, /* Horizontal total */ - 0x28, /* Horizontal displayed */ - 0x2A, /* Horizontal sync position */ - 0xff, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x01, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ -}; - -static uint8_t mode_40x24[] = -{ - 0x18, /* Horizontal total */ - 0x14, /* Horizontal displayed */ - 0x15, /* Horizontal sync position */ - 0xff, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x01, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ -}; - - -/* Font ROM: Two fonts, each containing 256 characters, 16x16 pixels */ -extern uint8_t fontdatw[512][32]; - -typedef struct wy700_t -{ - mem_mapping_t mapping; - - /* The microcontroller works by watching four ports: - * 0x3D8 / 0x3B8 (mode control register) - * 0x3DD (top scanline address) - * 0x3DF (Wy700 control register) - * CRTC reg 14 (cursor location high) - * - * It will do nothing until one of these registers is touched. When - * one is, it then reconfigures the internal 6845 based on what it - * sees. - */ - uint8_t last_03D8; /* Copies of values written to the listed */ - uint8_t last_03DD; /* I/O ports */ - uint8_t last_03DF; - uint8_t last_crtc_0E; - - uint8_t cga_crtc[32]; /* The 'CRTC' as the host PC sees it */ - uint8_t real_crtc[32]; /* The internal CRTC as the microcontroller */ - /* sees it */ - int cga_crtcreg; /* Current CRTC register */ - uint16_t wy700_base; /* Framebuffer base address (native modes) */ - uint8_t wy700_control; /* Native control / command register */ - uint8_t wy700_mode; /* Current mode (see list at top of file) */ - uint8_t cga_ctrl; /* Emulated MDA/CGA control register */ - uint8_t cga_colour; /* Emulated CGA colour register (ignored) */ - - uint8_t mda_stat; /* MDA status (IN 0x3BA) */ - uint8_t cga_stat; /* CGA status (IN 0x3DA) */ - - int font; /* Current font, 0 or 1 */ - int enabled; /* Display enabled, 0 or 1 */ - int detach; /* Detach cursor, 0 or 1 */ - - int64_t dispontime, dispofftime; - int64_t vidtime; - - int linepos, displine; - int vc; - int dispon, blink; - int64_t vsynctime; - - uint8_t *vram; -} wy700_t; - -/* Mapping of attributes to colours, in CGA emulation... */ -static int cgacols[256][2][2]; -/* ... and MDA emulation. */ -static int mdacols[256][2][2]; - -void wy700_recalctimings(wy700_t *wy700); -void wy700_write(uint32_t addr, uint8_t val, void *p); -uint8_t wy700_read(uint32_t addr, void *p); -void wy700_checkchanges(wy700_t *wy700); - - -void wy700_out(uint16_t addr, uint8_t val, void *p) -{ - wy700_t *wy700 = (wy700_t *)p; - switch (addr) - { - /* These three registers are only mapped in the 3Dx range, - * not the 3Bx range. */ - case 0x3DD: /* Base address (low) */ - wy700->wy700_base &= 0xFF00; - wy700->wy700_base |= val; - wy700_checkchanges(wy700); - break; - - case 0x3DE: /* Base address (high) */ - wy700->wy700_base &= 0xFF; - wy700->wy700_base |= ((uint16_t)val) << 8; - wy700_checkchanges(wy700); - break; - - case 0x3DF: /* Command / control register */ - wy700->wy700_control = val; - wy700_checkchanges(wy700); - break; - - /* Emulated CRTC, register select */ - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - wy700->cga_crtcreg = val & 31; - break; - - /* Emulated CRTC, value */ - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - wy700->cga_crtc[wy700->cga_crtcreg] = val; - - wy700_checkchanges(wy700); - wy700_recalctimings(wy700); - return; - - /* Emulated MDA / CGA control register */ - case 0x3b8: case 0x3D8: - wy700->cga_ctrl = val; - wy700_checkchanges(wy700); - return; - /* Emulated CGA colour register */ - case 0x3D9: - wy700->cga_colour = val; - return; - } -} - -uint8_t wy700_in(uint16_t addr, void *p) -{ - wy700_t *wy700 = (wy700_t *)p; - switch (addr) - { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - return wy700->cga_crtcreg; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - return wy700->cga_crtc[wy700->cga_crtcreg]; - case 0x3b8: case 0x3d8: - return wy700->cga_ctrl; - case 0x3d9: - return wy700->cga_colour; - case 0x3ba: - return wy700->mda_stat; - case 0x3da: - return wy700->cga_stat; - } - return 0xff; -} - - -/* Check if any of the four key registers has changed. If so, check for a - * mode change or cursor size change */ -void wy700_checkchanges(wy700_t *wy700) -{ - uint8_t curstart, curend; - - if (wy700->last_03D8 == wy700->cga_ctrl && - wy700->last_03DD == (wy700->wy700_base & 0xFF) && - wy700->last_03DF == wy700->wy700_control && - wy700->last_crtc_0E == wy700->cga_crtc[0x0E]) - { - return; /* Nothing changed */ - } - /* Check for control register changes */ - if (wy700->last_03DF != wy700->wy700_control) - { - wy700->last_03DF = wy700->wy700_control; - - /* Values 1-7 are commands. */ - switch (wy700->wy700_control) - { - case 1: /* Reset */ - wy700->font = 0; - wy700->enabled = 1; - wy700->detach = 0; - break; - - case 2: /* Font 1 */ - wy700->font = 0; - break; - - case 3: /* Font 2 */ - wy700->font = 1; - break; - -/* Even with the microprogram from an original card, I can't really work out - * what commands 4 and 5 (which I've called 'cursor detach' / 'cursor attach') - * do. Command 4 sets a flag in microcontroller RAM, and command 5 clears - * it. When the flag is set, the real cursor doesn't track the cursor in the - * emulated CRTC, and its blink rate increases. Possibly it's a self-test - * function of some kind. - * - * The card documentation doesn't cover these commands. - */ - - case 4: /* Detach cursor */ - wy700->detach = 1; - break; - - case 5: /* Attach cursor */ - wy700->detach = 0; - break; - - case 6: /* Disable display */ - wy700->enabled = 0; - break; - - case 7: /* Enable display */ - wy700->enabled = 1; - break; - } - /* A control write with the top bit set selects graphics mode */ - if (wy700->wy700_control & 0x80) - { - /* Select hi-res graphics mode; map framebuffer at A0000 */ - mem_mapping_set_addr(&wy700->mapping, 0xa0000, 0x20000); - wy700->wy700_mode = wy700->wy700_control; - - /* Select appropriate preset timings */ - if (wy700->wy700_mode & 0x40) - { - memcpy(wy700->real_crtc, mode_1280x800, - sizeof(mode_1280x800)); - } - else if (wy700->wy700_mode & 0x20) - { - memcpy(wy700->real_crtc, mode_1280x400, - sizeof(mode_1280x400)); - } - else - { - memcpy(wy700->real_crtc, mode_640x400, - sizeof(mode_640x400)); - } - } - } - /* An attempt to program the CGA / MDA selects low-res mode */ - else if (wy700->last_03D8 != wy700->cga_ctrl) - { - wy700->last_03D8 = wy700->cga_ctrl; - /* Set lo-res text or graphics mode. - * (Strictly speaking, when not in hi-res mode the card - * should be mapped at B0000-B3FFF and B8000-BBFFF, leaving - * a 16k hole between the two ranges) */ - mem_mapping_set_addr(&wy700->mapping, 0xb0000, 0x0C000); - if (wy700->cga_ctrl & 2) /* Graphics mode */ - { - wy700->wy700_mode = (wy700->cga_ctrl & 0x10) ? 6 : 4; - memcpy(wy700->real_crtc, mode_640x200, - sizeof(mode_640x200)); - } - else if (wy700->cga_ctrl & 1) /* Text mode 80x24 */ - { - wy700->wy700_mode = 2; - memcpy(wy700->real_crtc, mode_80x24, sizeof(mode_80x24)); - } - else /* Text mode 40x24 */ - { - wy700->wy700_mode = 0; - memcpy(wy700->real_crtc, mode_40x24, sizeof(mode_40x24)); - } - } - /* Convert the cursor sizes from the ones used by the CGA or MDA - * to native */ - - if (wy700->cga_crtc[9] == 13) /* MDA scaling */ - { - curstart = wy700->cga_crtc[10] & 0x1F; - wy700->real_crtc[10] = ((curstart + 5) >> 3) + curstart; - if (wy700->real_crtc[10] > 31) wy700->real_crtc[10] = 31; - /* And bring 'cursor disabled' flag across */ - if ((wy700->cga_crtc[10] & 0x60) == 0x20) - { - wy700->real_crtc[10] |= 0x20; - } - curend = wy700->cga_crtc[11] & 0x1F; - wy700->real_crtc[11] = ((curend + 5) >> 3) + curend; - if (wy700->real_crtc[11] > 31) wy700->real_crtc[11] = 31; - } - else /* CGA scaling */ - { - curstart = wy700->cga_crtc[10] & 0x1F; - wy700->real_crtc[10] = curstart << 1; - if (wy700->real_crtc[10] > 31) wy700->real_crtc[10] = 31; - /* And bring 'cursor disabled' flag across */ - if ((wy700->cga_crtc[10] & 0x60) == 0x20) - { - wy700->real_crtc[10] |= 0x20; - } - curend = wy700->cga_crtc[11] & 0x1F; - wy700->real_crtc[11] = curend << 1; - if (wy700->real_crtc[11] > 31) wy700->real_crtc[11] = 31; - } -} - - -void wy700_write(uint32_t addr, uint8_t val, void *p) -{ - wy700_t *wy700 = (wy700_t *)p; - egawrites++; - - if (wy700->wy700_mode & 0x80) /* High-res mode. */ - { - addr &= 0xFFFF; -/* In 800-line modes, bit 1 of the control register sets the high bit of the - * write address. */ - if ((wy700->wy700_mode & 0x42) == 0x42) - { - addr |= 0x10000; - } - wy700->vram[addr] = val; - } - else - { - wy700->vram[addr & 0x3fff] = val; - } -} - - - -uint8_t wy700_read(uint32_t addr, void *p) -{ - wy700_t *wy700 = (wy700_t *)p; - egareads++; - if (wy700->wy700_mode & 0x80) /* High-res mode. */ - { - addr &= 0xFFFF; -/* In 800-line modes, bit 0 of the control register sets the high bit of the - * read address. */ - if ((wy700->wy700_mode & 0x41) == 0x41) - { - addr |= 0x10000; - } - return wy700->vram[addr]; - } - else - { - return wy700->vram[addr & 0x3fff]; - } -} - - - -void wy700_recalctimings(wy700_t *wy700) -{ - double disptime; - double _dispontime, _dispofftime; - - disptime = wy700->real_crtc[0] + 1; - _dispontime = wy700->real_crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - wy700->dispontime = (int64_t)(_dispontime * (1 << TIMER_SHIFT)); - wy700->dispofftime = (int64_t)(_dispofftime * (1 << TIMER_SHIFT)); -} - - -/* Draw a single line of the screen in either text mode */ -void wy700_textline(wy700_t *wy700) -{ - int x; - int w = (wy700->wy700_mode == 0) ? 40 : 80; - int cw = (wy700->wy700_mode == 0) ? 32 : 16; - uint8_t chr, attr; - uint8_t bitmap[2]; - uint8_t *fontbase = &fontdatw[0][0]; - int blink, c; - int drawcursor, cursorline; - int mda = 0; - uint16_t addr; - uint8_t sc; - uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; - uint16_t ca = (wy700->cga_crtc[15] | (wy700->cga_crtc[14] << 8)) & 0x3fff; - - -/* The fake CRTC character height register selects whether MDA or CGA - * attributes are used */ - if (wy700->cga_crtc[9] == 0 || wy700->cga_crtc[9] == 13) - { - mda = 1; - } - - if (wy700->font) - { - fontbase += 256*32; - } - addr = ((ma & ~1) + (wy700->displine >> 5) * w) * 2; - sc = (wy700->displine >> 1) & 15; - - ma += ((wy700->displine >> 5) * w); - - if ((wy700->real_crtc[10] & 0x60) == 0x20) - { - cursorline = 0; - } - else - { - cursorline = ((wy700->real_crtc[10] & 0x1F) <= sc) && - ((wy700->real_crtc[11] & 0x1F) >= sc); - } - - for (x = 0; x < w; x++) - { - chr = wy700->vram[(addr + 2 * x) & 0x3FFF]; - attr = wy700->vram[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && wy700->enabled && - (wy700->cga_ctrl & 8) && (wy700->blink & 16)); - blink = ((wy700->blink & 16) && - (wy700->cga_ctrl & 0x20) && - (attr & 0x80) && !drawcursor); - - if (wy700->cga_ctrl & 0x20) attr &= 0x7F; - /* MDA underline */ - if (sc == 14 && mda && ((attr & 7) == 1)) - { - for (c = 0; c < cw; c++) - buffer->line[wy700->displine][(x * cw) + c] = - mdacols[attr][blink][1]; - } - else /* Draw 16 pixels of character */ - { - bitmap[0] = fontbase[chr * 32 + 2 * sc]; - bitmap[1] = fontbase[chr * 32 + 2 * sc + 1]; - for (c = 0; c < 16; c++) - { - int col; - if (c < 8) - col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; - else col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[1] & (1 << ((c & 7) ^ 7))) ? 1 : 0]; - if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) - col = mdacols[0][0][0]; - if (w == 40) - { - buffer->line[wy700->displine][(x * cw) + 2*c] = col; - buffer->line[wy700->displine][(x * cw) + 2*c + 1] = col; - } - else buffer->line[wy700->displine][(x * cw) + c] = col; - } - - if (drawcursor) - { - for (c = 0; c < cw; c++) - buffer->line[wy700->displine][(x * cw) + c] ^= (mda ? mdacols : cgacols)[attr][0][1]; - } - ++ma; - } - } -} - - -/* Draw a line in either of the CGA graphics modes (320x200 or 640x200) */ -void wy700_cgaline(wy700_t *wy700) -{ - int x, c; - uint32_t dat; - uint8_t ink = 0; - uint16_t addr; - - uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; - addr = ((wy700->displine >> 2) & 1) * 0x2000 + - (wy700->displine >> 3) * 80 + - ((ma & ~1) << 1); - - /* The fixed mode setting here programs the real CRTC with a screen - * width to 20, so draw in 20 fixed chunks of 4 bytes each */ - for (x = 0; x < 20; x++) - { - dat = ((wy700->vram[addr & 0x3FFF] << 24) | - (wy700->vram[(addr+1) & 0x3FFF] << 16) | - (wy700->vram[(addr+2) & 0x3FFF] << 8) | - (wy700->vram[(addr+3) & 0x3FFF])); - addr += 4; - - if (wy700->wy700_mode == 6) - { - for (c = 0; c < 32; c++) - { - ink = (dat & 0x80000000) ? 16 + 15: 16 + 0; - if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) - ink = 16; - buffer->line[wy700->displine][x*64 + 2*c] = - buffer->line[wy700->displine][x*64 + 2*c+1] = - ink; - dat = dat << 1; - } - } - else - { - for (c = 0; c < 16; c++) - { - switch ((dat >> 30) & 3) - { - case 0: ink = 16 + 0; break; - case 1: ink = 16 + 8; break; - case 2: ink = 16 + 7; break; - case 3: ink = 16 + 15; break; - } - if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) - ink = 16; - buffer->line[wy700->displine][x*64 + 4*c] = - buffer->line[wy700->displine][x*64 + 4*c+1] = - buffer->line[wy700->displine][x*64 + 4*c+2] = - buffer->line[wy700->displine][x*64 + 4*c+3] = - ink; - dat = dat << 2; - } - } - } -} - -/* Draw a line in the medium-resolution graphics modes (640x400 or 320x400) */ -void wy700_medresline(wy700_t *wy700) -{ - int x, c; - uint32_t dat; - uint8_t ink = 0; - uint32_t addr; - - addr = (wy700->displine >> 1) * 80 + 4 * wy700->wy700_base; - - for (x = 0; x < 20; x++) - { - dat = ((wy700->vram[addr & 0x1FFFF] << 24) | - (wy700->vram[(addr+1) & 0x1FFFF] << 16) | - (wy700->vram[(addr+2) & 0x1FFFF] << 8) | - (wy700->vram[(addr+3) & 0x1FFFF])); - addr += 4; - - if (wy700->wy700_mode & 0x10) - { - for (c = 0; c < 16; c++) - { - switch ((dat >> 30) & 3) - { - case 0: ink = 16 + 0; break; - case 1: ink = 16 + 8; break; - case 2: ink = 16 + 7; break; - case 3: ink = 16 + 15; break; - } - /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) ink = 16; - buffer->line[wy700->displine][x*64 + 4*c] = - buffer->line[wy700->displine][x*64 + 4*c+1] = - buffer->line[wy700->displine][x*64 + 4*c+2] = - buffer->line[wy700->displine][x*64 + 4*c+3] = - ink; - dat = dat << 2; - } - } - else - { - for (c = 0; c < 32; c++) - { - ink = (dat & 0x80000000) ? 16 + 15: 16 + 0; - /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) ink = 16; - buffer->line[wy700->displine][x*64 + 2*c] = - buffer->line[wy700->displine][x*64 + 2*c+1] = - ink; - dat = dat << 1; - } - } - } -} - - - - -/* Draw a line in one of the high-resolution modes */ -void wy700_hiresline(wy700_t *wy700) -{ - int x, c; - uint32_t dat; - uint8_t ink = 0; - uint32_t addr; - - addr = (wy700->displine >> 1) * 160 + 4 * wy700->wy700_base; - - if (wy700->wy700_mode & 0x40) /* 800-line interleaved modes */ - { - if (wy700->displine & 1) addr += 0x10000; - } - for (x = 0; x < 40; x++) - { - dat = ((wy700->vram[addr & 0x1FFFF] << 24) | - (wy700->vram[(addr+1) & 0x1FFFF] << 16) | - (wy700->vram[(addr+2) & 0x1FFFF] << 8) | - (wy700->vram[(addr+3) & 0x1FFFF])); - addr += 4; - - if (wy700->wy700_mode & 0x10) - { - for (c = 0; c < 16; c++) - { - switch ((dat >> 30) & 3) - { - case 0: ink = 16 + 0; break; - case 1: ink = 16 + 8; break; - case 2: ink = 16 + 7; break; - case 3: ink = 16 + 15; break; - } - /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) ink = 16; - buffer->line[wy700->displine][x*32 + 2*c] = - buffer->line[wy700->displine][x*32 + 2*c+1] = - ink; - dat = dat << 2; - } - } - else - { - for (c = 0; c < 32; c++) - { - ink = (dat & 0x80000000) ? 16 + 15: 16 + 0; - /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) ink = 16; - buffer->line[wy700->displine][x*32 + c] = ink; - dat = dat << 1; - } - } - } -} - - - - -void wy700_poll(void *p) -{ - wy700_t *wy700 = (wy700_t *)p; - int mode; - - if (!wy700->linepos) - { - wy700->vidtime += wy700->dispofftime; - wy700->cga_stat |= 1; - wy700->mda_stat |= 1; - wy700->linepos = 1; - if (wy700->dispon) - { - if (wy700->displine == 0) - { - video_wait_for_buffer(); - } - - if (wy700->wy700_mode & 0x80) - mode = wy700->wy700_mode & 0xF0; - else mode = wy700->wy700_mode & 0x0F; - - switch (mode) - { - default: - case 0x00: - case 0x02: - wy700_textline(wy700); - break; - case 0x04: - case 0x06: - wy700_cgaline(wy700); - break; - case 0x80: - case 0x90: - wy700_medresline(wy700); - break; - case 0xA0: - case 0xB0: - case 0xC0: - case 0xD0: - case 0xE0: - case 0xF0: - wy700_hiresline(wy700); - break; - } - } - wy700->displine++; - /* Hardcode a fixed refresh rate and VSYNC timing */ - if (wy700->displine == 800) /* Start of VSYNC */ - { - wy700->cga_stat |= 8; - wy700->dispon = 0; - } - if (wy700->displine == 832) /* End of VSYNC */ - { - wy700->displine = 0; - wy700->cga_stat &= ~8; - wy700->dispon = 1; - } - } - else - { - if (wy700->dispon) - { - wy700->cga_stat &= ~1; - wy700->mda_stat &= ~1; - } - wy700->vidtime += wy700->dispontime; - wy700->linepos = 0; - - if (wy700->displine == 800) - { -/* Hardcode 1280x800 window size */ - if ((WY700_XSIZE != xsize) || (WY700_YSIZE != ysize) || video_force_resize_get()) - { - xsize = WY700_XSIZE; - ysize = WY700_YSIZE; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen_8(0, 0, 0, ysize, xsize, ysize); - - frames++; - /* Fixed 1280x800 resolution */ - video_res_x = WY700_XSIZE; - video_res_y = WY700_YSIZE; - if (wy700->wy700_mode & 0x80) - mode = wy700->wy700_mode & 0xF0; - else mode = wy700->wy700_mode & 0x0F; - switch(mode) - { - case 0x00: - case 0x02: video_bpp = 0; break; - case 0x04: - case 0x90: - case 0xB0: - case 0xD0: - case 0xF0: video_bpp = 2; break; - default: video_bpp = 1; break; - } - wy700->blink++; - } - } -} - - -void *wy700_init(const device_t *info) -{ - int c; - wy700_t *wy700 = malloc(sizeof(wy700_t)); - memset(wy700, 0, sizeof(wy700_t)); - - /* 128k video RAM */ - wy700->vram = malloc(0x20000); - - loadfont(L"roms/video/wyse700/wy700.rom", 3); - - timer_add(wy700_poll, &wy700->vidtime, TIMER_ALWAYS_ENABLED, wy700); - - /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in - * high-resolution modes) */ - mem_mapping_add(&wy700->mapping, 0xb0000, 0x10000, wy700_read, NULL, NULL, wy700_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, wy700); - /* Respond to both MDA and CGA I/O ports */ - io_sethandler(0x03b0, 0x000C, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); - io_sethandler(0x03d0, 0x0010, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); - - /* Set up the emulated attributes. - * CGA is done in four groups: 00-0F, 10-7F, 80-8F, 90-FF */ - for (c = 0; c < 0x10; c++) - { - cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = 16; - if (c & 8) cgacols[c][0][1] = 15 + 16; - else cgacols[c][0][1] = 7 + 16; - } - for (c = 0x10; c < 0x80; c++) - { - cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = 16 + 7; - if (c & 8) cgacols[c][0][1] = 15 + 16; - else cgacols[c][0][1] = 0 + 16; - - if ((c & 0x0F) == 8) cgacols[c][0][1] = 8 + 16; - } - /* With special cases for 00, 11, 22, ... 77 */ - cgacols[0x00][0][1] = cgacols[0x00][1][1] = 16; - for (c = 0x11; c <= 0x77; c += 0x11) - { - cgacols[c][0][1] = cgacols[c][1][1] = 16 + 7; - } - for (c = 0x80; c < 0x90; c++) - { - cgacols[c][0][0] = 16 + 8; - if (c & 8) cgacols[c][0][1] = 15 + 16; - else cgacols[c][0][1] = 7 + 16; - cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c-0x80][0][0]; - } - for (c = 0x90; c < 0x100; c++) - { - cgacols[c][0][0] = 16 + 15; - if (c & 8) cgacols[c][0][1] = 8 + 16; - else cgacols[c][0][1] = 7 + 16; - if ((c & 0x0F) == 0) cgacols[c][0][1] = 16; - cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c-0x80][0][0]; - } - /* Also special cases for 99, AA, ..., FF */ - for (c = 0x99; c <= 0xFF; c += 0x11) - { - cgacols[c][0][1] = 16 + 15; - } - /* Special cases for 08, 80 and 88 */ - cgacols[0x08][0][1] = 16 + 8; - cgacols[0x80][0][1] = 16; - cgacols[0x88][0][1] = 16 + 8; - - /* MDA attributes */ - for (c = 0; c < 256; c++) - { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; - if (c & 8) mdacols[c][0][1] = 15 + 16; - else mdacols[c][0][1] = 7 + 16; - } - mdacols[0x70][0][1] = 16; - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15; - mdacols[0xF0][0][1] = 16; - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15; - mdacols[0x78][0][1] = 16 + 7; - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15; - mdacols[0xF8][0][1] = 16 + 7; - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; - -/* Start off in 80x25 text mode */ - wy700->cga_stat = 0xF4; - wy700->wy700_mode = 2; - wy700->enabled = 1; - memcpy(wy700->real_crtc, mode_80x24, sizeof(mode_80x24)); - return wy700; -} - -void wy700_close(void *p) -{ - wy700_t *wy700 = (wy700_t *)p; - - free(wy700->vram); - free(wy700); -} - -void wy700_speed_changed(void *p) -{ - wy700_t *wy700 = (wy700_t *)p; - - wy700_recalctimings(wy700); -} - -const device_t wy700_device = -{ - "Wyse 700", - DEVICE_ISA, 0, - wy700_init, - wy700_close, - NULL, - NULL, - wy700_speed_changed, - NULL, - NULL -}; diff --git a/backup code/video - Cópia/vid_wy700.h b/backup code/video - Cópia/vid_wy700.h deleted file mode 100644 index 0c8a986fe..000000000 --- a/backup code/video - Cópia/vid_wy700.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t wy700_device; diff --git a/backup code/video - Cópia/video.c b/backup code/video - Cópia/video.c deleted file mode 100644 index 48d9b7276..000000000 --- a/backup code/video - Cópia/video.c +++ /dev/null @@ -1,766 +0,0 @@ -/* - * 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. - * - * Main video-rendering module. - * - * Video timing settings - - * - * 8-bit - 1mb/sec - * B = 8 ISA clocks - * W = 16 ISA clocks - * L = 32 ISA clocks - * - * Slow 16-bit - 2mb/sec - * B = 6 ISA clocks - * W = 8 ISA clocks - * L = 16 ISA clocks - * - * Fast 16-bit - 4mb/sec - * B = 3 ISA clocks - * W = 3 ISA clocks - * L = 6 ISA clocks - * - * Slow VLB/PCI - 8mb/sec (ish) - * B = 4 bus clocks - * W = 8 bus clocks - * L = 16 bus clocks - * - * Mid VLB/PCI - - * B = 4 bus clocks - * W = 5 bus clocks - * L = 10 bus clocks - * - * Fast VLB/PCI - - * B = 3 bus clocks - * W = 3 bus clocks - * L = 4 bus clocks - * - * Version: @(#)video.c 1.0.23 2018/05/25 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../config.h" -#include "../timer.h" -#include "../plat.h" -#include "video.h" -#include "vid_svga.h" - - -enum { - VIDEO_ISA = 0, - VIDEO_BUS -}; - -bitmap_t *screen = NULL, - *buffer = NULL, - *buffer32 = NULL; -uint8_t fontdat[2048][8]; /* IBM CGA font */ -uint8_t fontdatm[2048][16]; /* IBM MDA font */ -uint8_t fontdatw[512][32]; /* Wyse700 font */ -uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ -dbcs_font_t *fontdatksc5601; /* Korean KSC-5601 font */ -dbcs_font_t *fontdatksc5601_user; /* Korean KSC-5601 user defined font */ -uint32_t pal_lookup[256]; -int xsize = 1, - ysize = 1; -int cga_palette = 0; -uint32_t *video_6to8 = NULL, - *video_15to32 = NULL, - *video_16to32 = NULL; -int egareads = 0, - egawrites = 0, - changeframecount = 2; -uint8_t rotatevga[8][256]; -int frames = 0; -int fullchange = 0; -uint8_t edatlookup[4][4]; -int overscan_x = 0, - overscan_y = 0; -int video_timing_read_b = 0, - video_timing_read_w = 0, - video_timing_read_l = 0; -int video_timing_write_b = 0, - video_timing_write_w = 0, - video_timing_write_l = 0; -int video_res_x = 0, - video_res_y = 0, - video_bpp = 0; -static int video_force_resize; -PALETTE cgapal = { - {0,0,0}, {0,42,0}, {42,0,0}, {42,21,0}, - {0,0,0}, {0,42,42}, {42,0,42}, {42,42,42}, - {0,0,0}, {21,63,21}, {63,21,21}, {63,63,21}, - {0,0,0}, {21,63,63}, {63,21,63}, {63,63,63}, - - {0,0,0}, {0,0,42}, {0,42,0}, {0,42,42}, - {42,0,0}, {42,0,42}, {42,21,00}, {42,42,42}, - {21,21,21}, {21,21,63}, {21,63,21}, {21,63,63}, - {63,21,21}, {63,21,63}, {63,63,21}, {63,63,63}, - - {0,0,0}, {0,21,0}, {0,0,42}, {0,42,42}, - {42,0,21}, {21,10,21}, {42,0,42}, {42,0,63}, - {21,21,21}, {21,63,21}, {42,21,42}, {21,63,63}, - {63,0,0}, {42,42,0}, {63,21,42}, {41,41,41}, - - {0,0,0}, {0,42,42}, {42,0,0}, {42,42,42}, - {0,0,0}, {0,42,42}, {42,0,0}, {42,42,42}, - {0,0,0}, {0,63,63}, {63,0,0}, {63,63,63}, - {0,0,0}, {0,63,63}, {63,0,0}, {63,63,63}, -}; -PALETTE cgapal_mono[6] = { - { /* 0 - green, 4-color-optimized contrast. */ - {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05}, - {0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a}, - {0x03,0x39,0x0d},{0x03,0x3c,0x0e},{0x00,0x07,0x01}, - {0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08}, - {0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17}, - }, - { /* 1 - green, 16-color-optimized contrast. */ - {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05}, - {0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08}, - {0x02,0x2e,0x0b},{0x02,0x31,0x0b},{0x01,0x22,0x08}, - {0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c}, - {0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17}, - }, - { /* 2 - amber, 4-color-optimized contrast. */ - {0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00}, - {0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00}, - {0x3f,0x26,0x01},{0x3f,0x2b,0x06},{0x0b,0x02,0x00}, - {0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00}, - {0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d}, - }, - { /* 3 - amber, 16-color-optimized contrast. */ - {0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00}, - {0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00}, - {0x38,0x1c,0x00},{0x3b,0x1e,0x00},{0x2c,0x13,0x00}, - {0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00}, - {0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d}, - }, - { /* 4 - grey, 4-color-optimized contrast. */ - {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x15,0x17,0x18}, - {0x18,0x1a,0x1b},{0x24,0x25,0x25},{0x27,0x28,0x28}, - {0x33,0x34,0x32},{0x37,0x38,0x35},{0x09,0x0a,0x0b}, - {0x11,0x12,0x13},{0x1c,0x1e,0x1e},{0x20,0x22,0x22}, - {0x2c,0x2d,0x2c},{0x2f,0x30,0x2f},{0x3c,0x3c,0x38},{0x3f,0x3f,0x3b}, - }, - { /* 5 - grey, 16-color-optimized contrast. */ - {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x13,0x14,0x15}, - {0x15,0x17,0x18},{0x1e,0x20,0x20},{0x20,0x22,0x22}, - {0x29,0x2a,0x2a},{0x2c,0x2d,0x2c},{0x1f,0x21,0x21}, - {0x23,0x25,0x25},{0x2b,0x2c,0x2b},{0x2d,0x2e,0x2d}, - {0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b}, - } -}; - - -static struct { - int x, y, y1, y2, w, h; - int busy; - int buffer_in_use; - - thread_t *blit_thread; - event_t *wake_blit_thread; - event_t *blit_complete; - event_t *buffer_not_in_use; -} blit_data; - - -static void (*blit_func)(int x, int y, int y1, int y2, int w, int h); - - -static -void blit_thread(void *param) -{ - while (1) { - thread_wait_event(blit_data.wake_blit_thread, -1); - thread_reset_event(blit_data.wake_blit_thread); - - if (blit_func) - blit_func(blit_data.x, blit_data.y, - blit_data.y1, blit_data.y2, - blit_data.w, blit_data.h); - - blit_data.busy = 0; - thread_set_event(blit_data.blit_complete); - } -} - - -void -video_setblit(void(*blit)(int,int,int,int,int,int)) -{ - blit_func = blit; -} - - -void -video_blit_complete(void) -{ - blit_data.buffer_in_use = 0; - - thread_set_event(blit_data.buffer_not_in_use); -} - - -void -video_wait_for_blit(void) -{ - while (blit_data.busy) - thread_wait_event(blit_data.blit_complete, -1); - thread_reset_event(blit_data.blit_complete); -} - - -void -video_wait_for_buffer(void) -{ - while (blit_data.buffer_in_use) - thread_wait_event(blit_data.buffer_not_in_use, -1); - thread_reset_event(blit_data.buffer_not_in_use); -} - - -void -video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) -{ - if (h <= 0) return; - - video_wait_for_blit(); - - blit_data.busy = 1; - blit_data.buffer_in_use = 1; - blit_data.x = x; - blit_data.y = y; - blit_data.y1 = y1; - blit_data.y2 = y2; - blit_data.w = w; - blit_data.h = h; - - thread_set_event(blit_data.wake_blit_thread); -} - - -void -video_blit_memtoscreen_8(int x, int y, int y1, int y2, int w, int h) -{ - int yy, xx; - - if (h <= 0) return; - - for (yy = 0; yy < h; yy++) - { - if ((y + yy) >= 0 && (y + yy) < buffer->h) - { - for (xx = 0; xx < w; xx++) - *(uint32_t *) &(buffer32->line[y + yy][(x + xx) << 2]) = pal_lookup[buffer->line[y + yy][x + xx]]; - } - } - - video_blit_memtoscreen(x, y, y1, y2, w, h); -} - - -void -cgapal_rebuild(void) -{ - int c; - - /* We cannot do this (yet) if we have not been enabled yet. */ - if (video_6to8 == NULL) return; - - for (c=0; c<256; c++) { - pal_lookup[c] = makecol(video_6to8[cgapal[c].r], - video_6to8[cgapal[c].g], - video_6to8[cgapal[c].b]); - } - - if ((cga_palette > 1) && (cga_palette < 8)) { - if (vid_cga_contrast != 0) { - for (c=0; c<16; c++) { - pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], - video_6to8[cgapal_mono[cga_palette - 2][c].g], - video_6to8[cgapal_mono[cga_palette - 2][c].b]); - pal_lookup[c+16] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], - video_6to8[cgapal_mono[cga_palette - 2][c].g], - video_6to8[cgapal_mono[cga_palette - 2][c].b]); - pal_lookup[c+32] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], - video_6to8[cgapal_mono[cga_palette - 2][c].g], - video_6to8[cgapal_mono[cga_palette - 2][c].b]); - pal_lookup[c+48] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], - video_6to8[cgapal_mono[cga_palette - 2][c].g], - video_6to8[cgapal_mono[cga_palette - 2][c].b]); - } - } else { - for (c=0; c<16; c++) { - pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], - video_6to8[cgapal_mono[cga_palette - 1][c].g], - video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c+16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], - video_6to8[cgapal_mono[cga_palette - 1][c].g], - video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c+32] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], - video_6to8[cgapal_mono[cga_palette - 1][c].g], - video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c+48] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], - video_6to8[cgapal_mono[cga_palette - 1][c].g], - video_6to8[cgapal_mono[cga_palette - 1][c].b]); - } - } - } - - if (cga_palette == 8) - pal_lookup[0x16] = makecol(video_6to8[42],video_6to8[42],video_6to8[0]); -} - - -static video_timings_t timing_dram = {VIDEO_BUS, 0,0,0, 0,0,0}; /*No additional waitstates*/ -static video_timings_t timing_pc1512 = {VIDEO_BUS, 0,0,0, 0,0,0}; /*PC1512 video code handles waitstates itself*/ -static video_timings_t timing_pc1640 = {VIDEO_ISA, 8,16,32, 8,16,32}; -static video_timings_t timing_pc200 = {VIDEO_ISA, 8,16,32, 8,16,32}; -static video_timings_t timing_m24 = {VIDEO_ISA, 8,16,32, 8,16,32}; -static video_timings_t timing_t1000 = {VIDEO_ISA, 8,16,32, 8,16,32}; -static video_timings_t timing_pvga1a = {VIDEO_ISA, 6, 8,16, 6, 8,16}; -static video_timings_t timing_wd90c11 = {VIDEO_ISA, 3, 3, 6, 5, 5,10}; -static video_timings_t timing_vga = {VIDEO_ISA, 8,16,32, 8,16,32}; -static video_timings_t timing_ps1_svga = {VIDEO_ISA, 6, 8,16, 6, 8,16}; -static video_timings_t timing_t3100e = {VIDEO_ISA, 8,16,32, 8,16,32}; -static video_timings_t timing_endeavor = {VIDEO_BUS, 3, 2, 4,25,25,40}; - -void -video_update_timing(void) -{ - video_timings_t *timing; - int new_gfxcard; - - new_gfxcard = 0; - - switch(romset) { - case ROM_IBMPCJR: - case ROM_TANDY: - case ROM_TANDY1000HX: - case ROM_TANDY1000SL2: - timing = &timing_dram; - break; - case ROM_PC1512: - timing = &timing_pc1512; - break; - case ROM_PC1640: - timing = &timing_pc1640; - break; - case ROM_PC200: - timing = &timing_pc200; - break; - case ROM_OLIM24: - timing = &timing_m24; - break; - case ROM_PC2086: - case ROM_PC3086: - timing = &timing_pvga1a; - break; - case ROM_T1000: - case ROM_T1200: - timing = &timing_t1000; - break; - case ROM_MEGAPC: - case ROM_MEGAPCDX: - timing = &timing_wd90c11; - break; - case ROM_IBMPS1_2011: - case ROM_IBMPS2_M30_286: - case ROM_IBMPS2_M50: - case ROM_IBMPS2_M55SX: - case ROM_IBMPS2_M80: - timing = &timing_vga; - break; - case ROM_IBMPS1_2121: - case ROM_IBMPS1_2133: - timing = &timing_ps1_svga; - break; - case ROM_T3100E: - timing = &timing_t3100e; - break; - case ROM_ENDEAVOR: - timing = &timing_endeavor; - break; - default: - new_gfxcard = video_old_to_new(gfxcard); - timing = video_card_gettiming(new_gfxcard); - break; - } - - if (timing->type == VIDEO_ISA) { - video_timing_read_b = ISA_CYCLES(timing->read_b); - video_timing_read_w = ISA_CYCLES(timing->read_w); - video_timing_read_l = ISA_CYCLES(timing->read_l); - video_timing_write_b = ISA_CYCLES(timing->write_b); - video_timing_write_w = ISA_CYCLES(timing->write_w); - video_timing_write_l = ISA_CYCLES(timing->write_l); - } else { - video_timing_read_b = (int)(bus_timing * timing->read_b); - video_timing_read_w = (int)(bus_timing * timing->read_w); - video_timing_read_l = (int)(bus_timing * timing->read_l); - video_timing_write_b = (int)(bus_timing * timing->write_b); - video_timing_write_w = (int)(bus_timing * timing->write_w); - video_timing_write_l = (int)(bus_timing * timing->write_l); - } - - if (cpu_16bitbus) { - video_timing_read_l = video_timing_read_w * 2; - video_timing_write_l = video_timing_write_w * 2; - } -} - - -int -calc_6to8(int c) -{ - int ic, i8; - double d8; - - ic = c; - if (ic == 64) - ic = 63; - else - ic &= 0x3f; - d8 = (ic / 63.0) * 255.0; - i8 = (int) d8; - - return(i8 & 0xff); -} - - -int -calc_15to32(int c) -{ - int b, g, r; - double db, dg, dr; - - b = (c & 31); - g = ((c >> 5) & 31); - r = ((c >> 10) & 31); - db = (((double) b) / 31.0) * 255.0; - dg = (((double) g) / 31.0) * 255.0; - dr = (((double) r) / 31.0) * 255.0; - b = (int) db; - g = ((int) dg) << 8; - r = ((int) dr) << 16; - - return(b | g | r); -} - - -int -calc_16to32(int c) -{ - int b, g, r; - double db, dg, dr; - - b = (c & 31); - g = ((c >> 5) & 63); - r = ((c >> 11) & 31); - db = (((double) b) / 31.0) * 255.0; - dg = (((double) g) / 63.0) * 255.0; - dr = (((double) r) / 31.0) * 255.0; - b = (int) db; - g = ((int) dg) << 8; - r = ((int) dr) << 16; - - return(b | g | r); -} - - -void -hline(bitmap_t *b, int x1, int y, int x2, uint32_t col) -{ - if (y < 0 || y >= buffer->h) - return; - - if (b == buffer) - memset(&b->line[y][x1], col, x2 - x1); - else - memset(&((uint32_t *)b->line[y])[x1], col, (x2 - x1) * 4); -} - - -void -blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int x2, int y2, int xs, int ys) -{ -} - - -void -stretch_blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int xs1, int ys1, int x2, int y2, int xs2, int ys2) -{ -} - - -void -rectfill(bitmap_t *b, int x1, int y1, int x2, int y2, uint32_t col) -{ -} - - -void -set_palette(PALETTE p) -{ -} - - -void -destroy_bitmap(bitmap_t *b) -{ - if (b->dat != NULL) - free(b->dat); - free(b); -} - - -bitmap_t * -create_bitmap(int x, int y) -{ - bitmap_t *b = malloc(sizeof(bitmap_t) + (y * sizeof(uint8_t *))); - int c; - - b->dat = malloc(x * y * 4); - for (c = 0; c < y; c++) - b->line[c] = b->dat + (c * x * 4); - b->w = x; - b->h = y; - - return(b); -} - - -void -video_init(void) -{ - int c, d, e; - - /* Account for overscan. */ - buffer32 = create_bitmap(2048, 2048); - - buffer = create_bitmap(2048, 2048); - for (c = 0; c < 64; c++) { - cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; - cgapal[c + 64].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; - cgapal[c + 64].b = (((c & 1) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; - if ((c & 0x17) == 6) - cgapal[c + 64].g >>= 1; - } - for (c = 0; c < 64; c++) { - cgapal[c + 128].r = (((c & 4) ? 2 : 0) | ((c & 0x20) ? 1 : 0)) * 21; - cgapal[c + 128].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; - cgapal[c + 128].b = (((c & 1) ? 2 : 0) | ((c & 0x08) ? 1 : 0)) * 21; - } - - for (c = 0; c < 256; c++) { - e = c; - for (d = 0; d < 8; d++) { - rotatevga[d][c] = e; - e = (e >> 1) | ((e & 1) ? 0x80 : 0); - } - } - for (c = 0; c < 4; c++) { - for (d = 0; d < 4; d++) { - edatlookup[c][d] = 0; - if (c & 1) edatlookup[c][d] |= 1; - if (d & 1) edatlookup[c][d] |= 2; - if (c & 2) edatlookup[c][d] |= 0x10; - if (d & 2) edatlookup[c][d] |= 0x20; - } - } - - video_6to8 = malloc(4 * 256); - for (c = 0; c < 256; c++) - video_6to8[c] = calc_6to8(c); - video_15to32 = malloc(4 * 65536); -#if 0 - for (c = 0; c < 65536; c++) - video_15to32[c] = ((c & 31) << 3) | (((c >> 5) & 31) << 11) | (((c >> 10) & 31) << 19); -#endif - for (c = 0; c < 65536; c++) - video_15to32[c] = calc_15to32(c); - - video_16to32 = malloc(4 * 65536); -#if 0 - for (c = 0; c < 65536; c++) - video_16to32[c] = ((c & 31) << 3) | (((c >> 5) & 63) << 10) | (((c >> 11) & 31) << 19); -#endif - for (c = 0; c < 65536; c++) - video_16to32[c] = calc_16to32(c); - - blit_data.wake_blit_thread = thread_create_event(); - blit_data.blit_complete = thread_create_event(); - blit_data.buffer_not_in_use = thread_create_event(); - blit_data.blit_thread = thread_create(blit_thread, NULL); -} - - -void -video_close(void) -{ - thread_kill(blit_data.blit_thread); - thread_destroy_event(blit_data.buffer_not_in_use); - thread_destroy_event(blit_data.blit_complete); - thread_destroy_event(blit_data.wake_blit_thread); - - free(video_6to8); - free(video_15to32); - free(video_16to32); - - destroy_bitmap(buffer); - destroy_bitmap(buffer32); - - if (fontdatksc5601) { - free(fontdatksc5601); - fontdatksc5601 = NULL; - } - - if (fontdatksc5601_user) { - free(fontdatksc5601_user); - fontdatksc5601_user = NULL; - } -} - - -uint8_t -video_force_resize_get(void) -{ - return video_force_resize; -} - - -void -video_force_resize_set(uint8_t res) -{ - video_force_resize = res; -} - - -void -loadfont(wchar_t *s, int format) -{ - FILE *f; - int c,d; - - f = rom_fopen(s, L"rb"); - if (f == NULL) - return; - - switch (format) { - case 0: /* MDA */ - for (c=0; c<256; c++) - for (d=0; d<8; d++) - fontdatm[c][d] = fgetc(f); - for (c=0; c<256; c++) - for (d=0; d<8; d++) - fontdatm[c][d+8] = fgetc(f); - (void)fseek(f, 4096+2048, SEEK_SET); - for (c=0; c<256; c++) - for (d=0; d<8; d++) - fontdat[c][d] = fgetc(f); - break; - - case 1: /* PC200 */ - for (c=0; c<256; c++) - for (d=0; d<8; d++) - fontdatm[c][d] = fgetc(f); - for (c=0; c<256; c++) - for (d=0; d<8; d++) - fontdatm[c][d+8] = fgetc(f); - (void)fseek(f, 4096, SEEK_SET); - for (c=0; c<256; c++) { - for (d=0; d<8; d++) - fontdat[c][d] = fgetc(f); - for (d=0; d<8; d++) (void)fgetc(f); - } - break; - - default: - case 2: /* CGA */ - for (c=0; c<256; c++) - for (d=0; d<8; d++) - fontdat[c][d] = fgetc(f); - break; - - case 3: /* Wyse 700 */ - for (c=0; c<512; c++) - for (d=0; d<32; d++) - fontdatw[c][d] = fgetc(f); - break; - - case 4: /* MDSI Genius */ - for (c=0; c<256; c++) - for (d=0; d<16; d++) - fontdat8x12[c][d] = fgetc(f); - break; - - case 5: /* Toshiba 3100e */ - for (d = 0; d < 2048; d += 512) /* Four languages... */ - { - for (c = d; c < d+256; c++) - { - fread(&fontdatm[c][8], 1, 8, f); - } - for (c = d+256; c < d+512; c++) - { - fread(&fontdatm[c][8], 1, 8, f); - } - for (c = d; c < d+256; c++) - { - fread(&fontdatm[c][0], 1, 8, f); - } - for (c = d+256; c < d+512; c++) - { - fread(&fontdatm[c][0], 1, 8, f); - } - fseek(f, 4096, SEEK_CUR); /* Skip blank section */ - for (c = d; c < d+256; c++) - { - fread(&fontdat[c][0], 1, 8, f); - } - for (c = d+256; c < d+512; c++) - { - fread(&fontdat[c][0], 1, 8, f); - } - } - break; - - case 6: /* Korean KSC-5601 */ - if (!fontdatksc5601) - fontdatksc5601 = malloc(16384 * sizeof(dbcs_font_t)); - - if (!fontdatksc5601_user) - fontdatksc5601_user = malloc(192 * sizeof(dbcs_font_t)); - - for (c = 0; c < 16384; c++) - { - for (d = 0; d < 32; d++) - fontdatksc5601[c].chr[d]=getc(f); - } - break; - } - - (void)fclose(f); -} diff --git a/backup code/video - Cópia/video.h b/backup code/video - Cópia/video.h deleted file mode 100644 index 36cee5b0d..000000000 --- a/backup code/video - Cópia/video.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * 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. - * - * Definitions for the video controller module. - * - * Version: @(#)video.h 1.0.28 2018/05/25 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#ifndef EMU_VIDEO_H -# define EMU_VIDEO_H - - -#define makecol(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) -#define makecol32(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) - - -enum { - GFX_NONE = 0, - GFX_INTERNAL, - GFX_CGA, - GFX_COMPAQ_CGA, /* Compaq CGA */ - GFX_COMPAQ_CGA_2, /* Compaq CGA 2 */ - GFX_COLORPLUS, /* Plantronics ColorPlus */ - GFX_WY700, /* Wyse 700 */ - GFX_MDA, - GFX_GENIUS, /* MDSI Genius */ - GFX_HERCULES, - GFX_HERCULESPLUS, - GFX_INCOLOR, /* Hercules InColor */ - GFX_EGA, /* Using IBM EGA BIOS */ - GFX_COMPAQ_EGA, /* Compaq EGA */ - GFX_SUPER_EGA, /* Using Chips & Technologies SuperEGA BIOS */ - GFX_VGA, /* IBM VGA */ - GFX_TVGA, /* Using Trident TVGA8900D BIOS */ - GFX_ET4000, /* Tseng ET4000 */ - GFX_ET4000W32_CARDEX_VLB, /* Tseng ET4000/W32p (Cardex) VLB */ - GFX_ET4000W32_CARDEX_PCI, /* Tseng ET4000/W32p (Cardex) PCI */ -#if defined(DEV_BRANCH) && defined(USE_STEALTH32) - GFX_ET4000W32_VLB, /* Tseng ET4000/W32p (Diamond Stealth 32) VLB */ - GFX_ET4000W32_PCI, /* Tseng ET4000/W32p (Diamond Stealth 32) PCI */ -#endif - GFX_BAHAMAS64_VLB, /* S3 Vision864 (Paradise Bahamas 64) VLB */ - GFX_BAHAMAS64_PCI, /* S3 Vision864 (Paradise Bahamas 64) PCI */ - GFX_N9_9FX_VLB, /* S3 764/Trio64 (Number Nine 9FX) VLB */ - GFX_N9_9FX_PCI, /* S3 764/Trio64 (Number Nine 9FX) PCI */ - GFX_TGUI9400CXI, /* Trident TGUI9400CXi VLB */ - GFX_TGUI9440_VLB, /* Trident TGUI9440AGi VLB */ - GFX_TGUI9440_PCI, /* Trident TGUI9440AGi PCI */ - GFX_ATIKOREANVGA, /*ATI Korean VGA (28800-5)*/ - GFX_VGA88, /* ATI VGA-88 (18800-1) */ - GFX_VGAEDGE16, /* ATI VGA Edge-16 (18800-1) */ - GFX_VGACHARGER, /* ATI VGA Charger (28800-5) */ -#if defined(DEV_BRANCH) && defined(USE_VGAWONDER) - GFX_VGAWONDER, /* Compaq ATI VGA Wonder (18800) */ -#endif - GFX_VGAWONDERXL, /* Compaq ATI VGA Wonder XL (28800-5) */ -#if defined(DEV_BRANCH) && defined(USE_XL24) - GFX_VGAWONDERXL24, /* Compaq ATI VGA Wonder XL24 (28800-6) */ -#endif - GFX_MACH64GX_ISA, /* ATI Graphics Pro Turbo (Mach64) ISA */ - GFX_MACH64GX_VLB, /* ATI Graphics Pro Turbo (Mach64) VLB */ - GFX_MACH64GX_PCI, /* ATI Graphics Pro Turbo (Mach64) PCI */ - GFX_MACH64VT2, /* ATI Mach64 VT2 */ - GFX_CL_GD5424_ISA, /* Cirrus Logic CL-GD 5424 ISA */ - GFX_CL_GD5424_VLB, /* Cirrus Logic CL-GD 5424 VLB */ - GFX_CL_GD5426_VLB, /* Diamond SpeedStar PRO (Cirrus Logic CL-GD 5426) VLB */ - GFX_CL_GD5428_ISA, /* Cirrus Logic CL-GD 5428 ISA */ - GFX_CL_GD5428_VLB, /* Cirrus Logic CL-GD 5428 VLB */ - GFX_CL_GD5429_ISA, /* Cirrus Logic CL-GD 5429 ISA */ - GFX_CL_GD5429_VLB, /* Cirrus Logic CL-GD 5429 VLB */ - GFX_CL_GD5430_VLB, /* Diamond SpeedStar PRO SE (Cirrus Logic CL-GD 5430) VLB */ - GFX_CL_GD5430_PCI, /* Cirrus Logic CL-GD 5430 PCI */ - GFX_CL_GD5434_ISA, /* Cirrus Logic CL-GD 5434 ISA */ - GFX_CL_GD5434_VLB, /* Cirrus Logic CL-GD 5434 VLB */ - GFX_CL_GD5434_PCI, /* Cirrus Logic CL-GD 5434 PCI */ - GFX_CL_GD5436_PCI, /* Cirrus Logic CL-GD 5436 PCI */ - GFX_CL_GD5440_PCI, /* Cirrus Logic CL-GD 5440 PCI */ - GFX_CL_GD5446_PCI, /* Cirrus Logic CL-GD 5446 PCI */ - GFX_CL_GD5446_STB_PCI, /* STB Nitro 64V (Cirrus Logic CL-GD 5446) PCI */ - GFX_CL_GD5480_PCI, /* Cirrus Logic CL-GD 5480 PCI */ -#if defined(DEV_BRANCH) && defined(USE_RIVA) - GFX_RIVATNT, /* nVidia Riva TNT */ - GFX_RIVATNT2, /* nVidia Riva TNT2 */ - GFX_RIVA128, /* nVidia Riva 128 */ -#endif - GFX_OTI037C, /* Oak OTI-037C */ - GFX_OTI067, /* Oak OTI-067 */ - GFX_OTI077, /* Oak OTI-077 */ - GFX_PVGA1A, /* Paradise PVGA1A Standalone */ - GFX_WD90C11, /* Paradise WD90C11-LR Standalone */ - GFX_WD90C30, /* Paradise WD90C30-LR Standalone */ - GFX_PHOENIX_TRIO32_VLB, /* S3 732/Trio32 (Phoenix) VLB */ - GFX_PHOENIX_TRIO32_PCI, /* S3 732/Trio32 (Phoenix) PCI */ - GFX_PHOENIX_TRIO64_VLB, /* S3 764/Trio64 (Phoenix) VLB */ - GFX_PHOENIX_TRIO64_PCI, /* S3 764/Trio64 (Phoenix) PCI */ - GFX_VIRGE_VLB, /* S3 Virge VLB */ - GFX_VIRGE_PCI, /* S3 Virge PCI */ - GFX_VIRGEDX_VLB, /* S3 Virge/DX VLB */ - GFX_VIRGEDX_PCI, /* S3 Virge/DX PCI */ - GFX_VIRGEDX4_VLB, /* S3 Virge/DX (VBE 2.0) VLB */ - GFX_VIRGEDX4_PCI, /* S3 Virge/DX (VBE 2.0) PCI */ - GFX_VIRGEVX_VLB, /* S3 Virge/VX VLB */ - GFX_VIRGEVX_PCI, /* S3 Virge/VX PCI */ - GFX_STEALTH64_VLB, /* S3 Vision864 (Diamond Stealth 64) VLB */ - GFX_STEALTH64_PCI, /* S3 Vision864 (Diamond Stealth 64) PCI */ - GFX_PHOENIX_VISION864_VLB, /* S3 Vision864 (Phoenix) VLB */ - GFX_PHOENIX_VISION864_PCI, /* S3 Vision864 (Phoenix) PCI */ -#if defined(DEV_BRANCH) && defined(USE_TI) - GFX_TICF62011, /* TI CF62011 */ -#endif - - GFX_MAX -}; - -enum { - FULLSCR_SCALE_FULL = 0, - FULLSCR_SCALE_43, - FULLSCR_SCALE_SQ, - FULLSCR_SCALE_INT, - FULLSCR_SCALE_KEEPRATIO -}; - - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef struct { - int type; - int write_b, write_w, write_l; - int read_b, read_w, read_l; -} video_timings_t; - -typedef struct { - int w, h; - uint8_t *dat; - uint8_t *line[]; -} bitmap_t; - -typedef struct { - uint8_t r, g, b; -} rgb_t; - -typedef struct { - uint8_t chr[32]; -} dbcs_font_t; - -typedef rgb_t PALETTE[256]; - - -extern int gfx_present[GFX_MAX]; -extern int egareads, - egawrites; -extern int changeframecount; - -extern bitmap_t *screen, - *buffer, - *buffer32; -extern PALETTE cgapal, - cgapal_mono[6]; -extern uint32_t pal_lookup[256]; -extern int video_fullscreen, - video_fullscreen_scale, - video_fullscreen_first; -extern int fullchange; -extern uint8_t fontdat[2048][8]; -extern uint8_t fontdatm[2048][16]; -extern dbcs_font_t *fontdatksc5601; -extern dbcs_font_t *fontdatksc5601_user; -extern uint32_t *video_6to8, - *video_15to32, - *video_16to32; -extern int xsize,ysize; -extern int enable_overscan; -extern int overscan_x, - overscan_y; -extern int force_43; -extern int video_timing_read_b, - video_timing_read_w, - video_timing_read_l; -extern int video_timing_write_b, - video_timing_write_w, - video_timing_write_l; -extern int video_res_x, - video_res_y, - video_bpp; -extern int vid_resize; -extern int cga_palette; -extern int vid_cga_contrast; -extern int video_grayscale; -extern int video_graytype; - -extern float cpuclock; -extern int emu_fps, - frames; -extern int readflash; - - -/* Function handler pointers. */ -extern void (*video_recalctimings)(void); - - -/* Table functions. */ -extern int video_card_available(int card); -extern char *video_card_getname(int card); -#ifdef EMU_DEVICE_H -extern const device_t *video_card_getdevice(int card); -#endif -extern int video_card_has_config(int card); -extern video_timings_t *video_card_gettiming(int card); -extern int video_card_getid(char *s); -extern int video_old_to_new(int card); -extern int video_new_to_old(int card); -extern char *video_get_internal_name(int card); -extern int video_get_video_from_internal_name(char *s); -extern int video_is_mda(void); -extern int video_is_cga(void); -extern int video_is_ega_vga(void); - - -extern void video_setblit(void(*blit)(int,int,int,int,int,int)); -extern void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); -extern void video_blit_memtoscreen_8(int x, int y, int y1, int y2, int w, int h); -extern void video_blit_complete(void); -extern void video_wait_for_blit(void); -extern void video_wait_for_buffer(void); - -extern bitmap_t *create_bitmap(int w, int h); -extern void destroy_bitmap(bitmap_t *b); -extern void cgapal_rebuild(void); -extern void hline(bitmap_t *b, int x1, int y, int x2, uint32_t col); -extern void updatewindowsize(int x, int y); - -extern void video_init(void); -extern void video_close(void); -extern void video_reset(int card); -extern uint8_t video_force_resize_get(void); -extern void video_force_resize_set(uint8_t res); -extern void video_update_timing(void); - -extern void loadfont(wchar_t *s, int format); - -extern int get_actual_size_x(void); -extern int get_actual_size_y(void); - -#ifdef ENABLE_VRAM_DUMP -extern void svga_dump_vram(void); -#endif - -#ifdef __cplusplus -} -#endif - - -#endif /*EMU_VIDEO_H*/ diff --git a/backup code/video/vid_cl54xx - Cópia.c b/backup code/video/vid_cl54xx - Cópia.c deleted file mode 100644 index 3388b2647..000000000 --- a/backup code/video/vid_cl54xx - Cópia.c +++ /dev/null @@ -1,2685 +0,0 @@ -/* - * 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 select Cirrus Logic cards (CL-GD 5428, - * CL-GD 5429, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). - * - * Version: @(#)vid_cl_54xx.c 1.0.19 2018/05/08 - * - * Authors: Sarah Walker, - * Barry Rodewald, - * TheCollector1995, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2018 Barry Rodewald - * Copyright 2016-2018 TheCollector1995. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_svga_render.h" -#include "vid_cl54xx.h" - -#define BIOS_GD5426_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin" -#define BIOS_GD5428_ISA_PATH L"roms/video/cirruslogic/5428.bin" -#define BIOS_GD5428_PATH L"roms/video/cirruslogic/vlbusjapan.BIN" -#define BIOS_GD5429_PATH L"roms/video/cirruslogic/5429.vbi" -#define BIOS_GD5430_VLB_PATH L"roms/video/cirruslogic/diamondvlbus.bin" -#define BIOS_GD5430_PCI_PATH L"roms/video/cirruslogic/pci.bin" -#define BIOS_GD5434_PATH L"roms/video/cirruslogic/gd5434.bin" -#define BIOS_GD5436_PATH L"roms/video/cirruslogic/5436.vbi" -#define BIOS_GD5440_PATH L"roms/video/cirruslogic/BIOS.BIN" -#define BIOS_GD5446_PATH L"roms/video/cirruslogic/5446BV.VBI" -#define BIOS_GD5446_STB_PATH L"roms/video/cirruslogic/stb nitro64v.BIN" -#define BIOS_GD5480_PATH L"roms/video/cirruslogic/clgd5480.rom" - -#define CIRRUS_ID_CLGD5426 0x90 -#define CIRRUS_ID_CLGD5428 0x98 -#define CIRRUS_ID_CLGD5429 0x9c -#define CIRRUS_ID_CLGD5430 0xa0 -#define CIRRUS_ID_CLGD5434 0xa8 -#define CIRRUS_ID_CLGD5436 0xac -#define CIRRUS_ID_CLGD5440 0xa0 /* Yes, the 5440 has the same ID as the 5430. */ -#define CIRRUS_ID_CLGD5446 0xb8 -#define CIRRUS_ID_CLGD5480 0xbc - -/* sequencer 0x07 */ -#define CIRRUS_SR7_BPP_VGA 0x00 -#define CIRRUS_SR7_BPP_SVGA 0x01 -#define CIRRUS_SR7_BPP_MASK 0x0e -#define CIRRUS_SR7_BPP_8 0x00 -#define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02 -#define CIRRUS_SR7_BPP_24 0x04 -#define CIRRUS_SR7_BPP_16 0x06 -#define CIRRUS_SR7_BPP_32 0x08 -#define CIRRUS_SR7_ISAADDR_MASK 0xe0 - -/* sequencer 0x12 */ -#define CIRRUS_CURSOR_SHOW 0x01 -#define CIRRUS_CURSOR_HIDDENPEL 0x02 -#define CIRRUS_CURSOR_LARGE 0x04 /* 64x64 if set, 32x32 if clear */ - -// sequencer 0x17 -#define CIRRUS_BUSTYPE_VLBFAST 0x10 -#define CIRRUS_BUSTYPE_PCI 0x20 -#define CIRRUS_BUSTYPE_VLBSLOW 0x30 -#define CIRRUS_BUSTYPE_ISA 0x38 -#define CIRRUS_MMIO_ENABLE 0x04 -#define CIRRUS_MMIO_USE_PCIADDR 0x40 /* 0xb8000 if cleared. */ -#define CIRRUS_MEMSIZEEXT_DOUBLE 0x80 - -// control 0x0b -#define CIRRUS_BANKING_DUAL 0x01 -#define CIRRUS_BANKING_GRANULARITY_16K 0x20 /* set:16k, clear:4k */ - -/* control 0x30 */ -#define CIRRUS_BLTMODE_BACKWARDS 0x01 -#define CIRRUS_BLTMODE_MEMSYSDEST 0x02 -#define CIRRUS_BLTMODE_MEMSYSSRC 0x04 -#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08 -#define CIRRUS_BLTMODE_PATTERNCOPY 0x40 -#define CIRRUS_BLTMODE_COLOREXPAND 0x80 -#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30 -#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00 -#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10 -#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20 -#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30 - -// control 0x31 -#define CIRRUS_BLT_BUSY 0x01 -#define CIRRUS_BLT_START 0x02 -#define CIRRUS_BLT_RESET 0x04 -#define CIRRUS_BLT_FIFOUSED 0x10 -#define CIRRUS_BLT_AUTOSTART 0x80 - -// control 0x33 -#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04 -#define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02 -#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01 - -#define CL_GD5429_SYSTEM_BUS_VESA 5 -#define CL_GD5429_SYSTEM_BUS_ISA 7 - -#define CL_GD543X_SYSTEM_BUS_PCI 4 -#define CL_GD543X_SYSTEM_BUS_VESA 6 -#define CL_GD543X_SYSTEM_BUS_ISA 7 - -typedef struct gd54xx_t -{ - mem_mapping_t mmio_mapping; - mem_mapping_t linear_mapping; - - svga_t svga; - - int has_bios, rev; - rom_t bios_rom; - - uint32_t vram_size; - uint32_t vram_mask; - - uint8_t vclk_n[4]; - uint8_t vclk_d[4]; - uint32_t bank[2]; - - struct { - uint8_t state; - int ctrl; - } ramdac; - - struct { - uint32_t fg_col, bg_col; - uint16_t width, height; - uint16_t dst_pitch, src_pitch; - uint32_t dst_addr, src_addr; - uint8_t mask, mode, rop; - uint8_t modeext; - uint8_t status; - uint16_t trans_col, trans_mask; - - uint32_t dst_addr_backup, src_addr_backup; - uint16_t width_backup, height_internal; - - int x_count, y_count; - int sys_tx; - uint8_t sys_cnt; - uint32_t sys_buf; - uint16_t pixel_cnt; - uint16_t scan_cnt; - } blt; - - int pci, vlb; - - uint8_t pci_regs[256]; - uint8_t int_line; - - int card; - - uint32_t lfb_base; - - int mmio_vram_overlap; - - uint32_t extpallook[256]; - PALETTE extpal; -} gd54xx_t; - -static void -gd543x_mmio_write(uint32_t addr, uint8_t val, void *p); -static void -gd543x_mmio_writew(uint32_t addr, uint16_t val, void *p); -static void -gd543x_mmio_writel(uint32_t addr, uint32_t val, void *p); -static uint8_t -gd543x_mmio_read(uint32_t addr, void *p); -static uint16_t -gd543x_mmio_readw(uint32_t addr, void *p); -static uint32_t -gd543x_mmio_readl(uint32_t addr, void *p); - -static void -gd54xx_recalc_banking(gd54xx_t *gd54xx); - -static void -gd543x_recalc_mapping(gd54xx_t *gd54xx); - -static void -gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga); - - -/* Returns 1 if the card is a 5434, 5436/46, or 5480. */ -static int -gd54xx_is_5434(svga_t *svga) -{ - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) - return 1; - else - return 0; -} - - -static void -gd54xx_out(uint16_t addr, uint8_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - uint8_t old; - int c; - uint8_t o; - uint32_t o32; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) { - case 0x3c0: - case 0x3c1: - if (!svga->attrff) { - svga->attraddr = val & 31; - if ((val & 0x20) != svga->attr_palette_enable) { - svga->fullchange = 3; - svga->attr_palette_enable = val & 0x20; - svga_recalctimings(svga); - } - } else { - o = svga->attrregs[svga->attraddr & 31]; - svga->attrregs[svga->attraddr & 31] = val; - if (svga->attraddr < 16) - svga->fullchange = changeframecount; - if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { - for (c = 0; c < 16; c++) { - if (svga->attrregs[0x10] & 0x80) svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); - else svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); - } - } - /* Recalculate timings on change of attribute register 0x11 (overscan border color) too. */ - if (svga->attraddr == 0x10) { - if (o != val) - svga_recalctimings(svga); - } else if (svga->attraddr == 0x11) { - if (!(svga->seqregs[0x12] & 0x80)) { - svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; - if (o != val) svga_recalctimings(svga); - } - } else if (svga->attraddr == 0x12) { - if ((val & 0xf) != svga->plane_mask) - svga->fullchange = changeframecount; - svga->plane_mask = val & 0xf; - } - } - svga->attrff ^= 1; - return; - case 0x3c4: - svga->seqaddr = val; - break; - case 0x3c5: - if (svga->seqaddr > 5) { - o = svga->seqregs[svga->seqaddr & 0x1f]; - svga->seqregs[svga->seqaddr & 0x1f] = val; - switch (svga->seqaddr & 0x1f) { - case 6: - val &= 0x17; - if (val == 0x12) - svga->seqregs[6] = 0x12; - else - svga->seqregs[6] = 0x0f; - break; - case 0x0b: case 0x0c: case 0x0d: case 0x0e: /* VCLK stuff */ - gd54xx->vclk_n[svga->seqaddr-0x0b] = val; - break; - case 0x1b: case 0x1c: case 0x1d: case 0x1e: /* VCLK stuff */ - gd54xx->vclk_d[svga->seqaddr-0x1b] = val; - break; - case 0x10: case 0x30: case 0x50: case 0x70: - case 0x90: case 0xb0: case 0xd0: case 0xf0: - svga->hwcursor.x = (val << 3) | (svga->seqaddr >> 5); - break; - case 0x11: case 0x31: case 0x51: case 0x71: - case 0x91: case 0xb1: case 0xd1: case 0xf1: - svga->hwcursor.y = (val << 3) | (svga->seqaddr >> 5); - break; - case 0x12: - if (val & 0x80) - svga->overscan_color = gd54xx->extpallook[2]; - else - svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; - svga_recalctimings(svga); - svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW; - svga->hwcursor.xsize = svga->hwcursor.ysize = (val & CIRRUS_CURSOR_LARGE) ? 64 : 32; - if (val & CIRRUS_CURSOR_LARGE) - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256)); - else - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3f) * 256)); - break; - case 0x13: - if (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3c) * 256)); - else - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3f) * 256)); - break; - case 0x07: - svga->set_reset_disabled = svga->seqregs[7] & 1; - case 0x17: - gd543x_recalc_mapping(gd54xx); - break; - } - return; - } - break; - case 0x3C6: - if (gd54xx->ramdac.state == 4) { - gd54xx->ramdac.state = 0; - gd54xx->ramdac.ctrl = val; - svga_recalctimings(svga); - return; - } - gd54xx->ramdac.state = 0; - break; - case 0x3C9: - 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: - if (svga->seqregs[0x12] & 2) { - gd54xx->extpal[svga->dac_write].r = svga->dac_r; - gd54xx->extpal[svga->dac_write].g = svga->dac_g; - gd54xx->extpal[svga->dac_write].b = val; - gd54xx->extpallook[svga->dac_write & 15] = makecol32(video_6to8[gd54xx->extpal[svga->dac_write].r & 0x3f], video_6to8[gd54xx->extpal[svga->dac_write].g & 0x3f], video_6to8[gd54xx->extpal[svga->dac_write].b & 0x3f]); - if ((svga->seqregs[0x12] & 0x80) && ((svga->dac_write & 15) == 2)) { - o32 = svga->overscan_color; - svga->overscan_color = gd54xx->extpallook[2]; - if (o32 != svga->overscan_color) - svga_recalctimings(svga); - } - svga->dac_write = (svga->dac_write + 1) & 15; - } else { - svga->vgapal[svga->dac_write].r = svga->dac_r; - svga->vgapal[svga->dac_write].g = svga->dac_g; - svga->vgapal[svga->dac_write].b = val; - svga->pallook[svga->dac_write] = makecol32(video_6to8[svga->vgapal[svga->dac_write].r & 0x3f], video_6to8[svga->vgapal[svga->dac_write].g & 0x3f], video_6to8[svga->vgapal[svga->dac_write].b & 0x3f]); - svga->dac_write = (svga->dac_write + 1) & 255; - } - svga->dac_pos = 0; - break; - } - return; - case 0x3cf: - if (svga->gdcaddr == 0) - gd543x_mmio_write(0xb8000, val, gd54xx); - if (svga->gdcaddr == 1) - gd543x_mmio_write(0xb8004, val, gd54xx); - - if (svga->gdcaddr == 5) { - svga->gdcreg[5] = val; - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = svga->gdcreg[5] & 7; - else - svga->writemode = svga->gdcreg[5] & 3; - svga->readmode = val & 8; - svga->chain2_read = val & 0x10; - return; - } - - if (svga->gdcaddr == 6) { - if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { - svga->gdcreg[6] = val; - gd543x_recalc_mapping(gd54xx); - } - svga->gdcreg[6] = val; - return; - } - - if (svga->gdcaddr > 8) { - svga->gdcreg[svga->gdcaddr & 0x3f] = val; - switch (svga->gdcaddr) { - case 0x09: case 0x0a: case 0x0b: - gd54xx_recalc_banking(gd54xx); - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = svga->gdcreg[5] & 7; - else - svga->writemode = svga->gdcreg[5] & 3; - break; - - case 0x10: - gd543x_mmio_write(0xb8001, val, gd54xx); - break; - case 0x11: - gd543x_mmio_write(0xb8005, val, gd54xx); - break; - case 0x12: - gd543x_mmio_write(0xb8002, val, gd54xx); - break; - case 0x13: - gd543x_mmio_write(0xb8006, val, gd54xx); - break; - case 0x14: - gd543x_mmio_write(0xb8003, val, gd54xx); - break; - case 0x15: - gd543x_mmio_write(0xb8007, val, gd54xx); - break; - - case 0x20: - gd543x_mmio_write(0xb8008, val, gd54xx); - break; - case 0x21: - gd543x_mmio_write(0xb8009, val, gd54xx); - break; - case 0x22: - gd543x_mmio_write(0xb800a, val, gd54xx); - break; - case 0x23: - gd543x_mmio_write(0xb800b, val, gd54xx); - break; - case 0x24: - gd543x_mmio_write(0xb800c, val, gd54xx); - break; - case 0x25: - gd543x_mmio_write(0xb800d, val, gd54xx); - break; - case 0x26: - gd543x_mmio_write(0xb800e, val, gd54xx); - break; - case 0x27: - gd543x_mmio_write(0xb800f, val, gd54xx); - break; - - case 0x28: - gd543x_mmio_write(0xb8010, val, gd54xx); - break; - case 0x29: - gd543x_mmio_write(0xb8011, val, gd54xx); - break; - case 0x2a: - gd543x_mmio_write(0xb8012, val, gd54xx); - break; - - case 0x2c: - gd543x_mmio_write(0xb8014, val, gd54xx); - break; - case 0x2d: - gd543x_mmio_write(0xb8015, val, gd54xx); - break; - case 0x2e: - gd543x_mmio_write(0xb8016, val, gd54xx); - break; - - case 0x2f: - gd543x_mmio_write(0xb8017, val, gd54xx); - break; - case 0x30: - gd543x_mmio_write(0xb8018, val, gd54xx); - break; - - case 0x32: - gd543x_mmio_write(0xb801a, val, gd54xx); - break; - - case 0x33: - gd543x_mmio_write(0xb801b, val, gd54xx); - break; - - case 0x31: - gd543x_mmio_write(0xb8040, val, gd54xx); - break; - - case 0x34: - gd543x_mmio_write(0xb801c, val, gd54xx); - break; - - case 0x35: - gd543x_mmio_write(0xb801d, val, gd54xx); - break; - - case 0x38: - gd543x_mmio_write(0xb8020, val, gd54xx); - break; - - case 0x39: - gd543x_mmio_write(0xb8021, val, gd54xx); - break; - - } - return; - } - break; - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); -} - - -static uint8_t -gd54xx_in(uint16_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - uint8_t temp; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3d0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) { - case 0x3c4: - if ((svga->seqregs[6] & 0x17) == 0x12) - { - temp = svga->seqaddr; - if ((temp & 0x1e) == 0x10) - { - if (temp & 1) - temp = ((svga->hwcursor.y & 7) << 5) | 0x11; - else - temp = ((svga->hwcursor.x & 7) << 5) | 0x10; - } - return temp; - } - return svga->seqaddr; - - case 0x3c5: - if (svga->seqaddr > 5) { - switch (svga->seqaddr) { - case 6: - return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; - case 0x0b: case 0x0c: case 0x0d: case 0x0e: - return gd54xx->vclk_n[svga->seqaddr-0x0b]; - case 0x17: - temp = svga->gdcreg[0x17] & ~(7 << 3); - if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) { - if (gd54xx->vlb) - temp |= (CL_GD5429_SYSTEM_BUS_VESA << 3); - else - temp |= (CL_GD5429_SYSTEM_BUS_ISA << 3); - } else { - if (gd54xx->pci) - temp |= (CL_GD543X_SYSTEM_BUS_PCI << 3); - else if (gd54xx->vlb) - temp |= (CL_GD543X_SYSTEM_BUS_VESA << 3); - else - temp |= (CL_GD543X_SYSTEM_BUS_ISA << 3); - } - return temp; - case 0x1b: case 0x1c: case 0x1d: case 0x1e: - return gd54xx->vclk_d[svga->seqaddr-0x1b]; - } - return svga->seqregs[svga->seqaddr & 0x3f]; - } - break; - case 0x3c9: - svga->dac_status = 3; - switch (svga->dac_pos) { - case 0: - svga->dac_pos++; - if (svga->seqregs[0x12] & 2) - return gd54xx->extpal[svga->dac_read].r & 0x3f; - else - return svga->vgapal[svga->dac_read].r & 0x3f; - case 1: - svga->dac_pos++; - if (svga->seqregs[0x12] & 2) - return gd54xx->extpal[svga->dac_read].g & 0x3f; - else - return svga->vgapal[svga->dac_read].g & 0x3f; - case 2: - svga->dac_pos=0; - if (svga->seqregs[0x12] & 2) { - svga->dac_read = (svga->dac_read + 1) & 15; - return gd54xx->extpal[(svga->dac_read - 1) & 15].b & 0x3f; - } else { - svga->dac_read = (svga->dac_read + 1) & 255; - return svga->vgapal[(svga->dac_read - 1) & 255].b & 0x3f; - } - } - return 0xFF; - case 0x3C6: - if (gd54xx->ramdac.state == 4) { - gd54xx->ramdac.state = 0; - return gd54xx->ramdac.ctrl; - } - gd54xx->ramdac.state++; - break; - case 0x3cf: - if (svga->gdcaddr > 8) { - return svga->gdcreg[svga->gdcaddr & 0x3f]; - } - break; - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - switch (svga->crtcreg) { - case 0x24: /*Attribute controller toggle readback (R)*/ - return svga->attrff << 7; - case 0x26: /*Attribute controller index readback (R)*/ - return svga->attraddr & 0x3f; - case 0x27: /*ID*/ - return svga->crtc[0x27]; /*GD542x/GD543x*/ - case 0x28: /*Class ID*/ - if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5430) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5440)) - return 0xff; /*Standard CL-GD5430/40*/ - break; - } - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); -} - - -static void -gd54xx_recalc_banking(gd54xx_t *gd54xx) -{ - svga_t *svga = &gd54xx->svga; - - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) - gd54xx->bank[0] = svga->gdcreg[0x09] << 14; - else - gd54xx->bank[0] = svga->gdcreg[0x09] << 12; - - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) { - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) - gd54xx->bank[1] = svga->gdcreg[0x0a] << 14; - else - gd54xx->bank[1] = svga->gdcreg[0x0a] << 12; - } else - gd54xx->bank[1] = gd54xx->bank[0] + 0x8000; -} - - -static void -gd543x_recalc_mapping(gd54xx_t *gd54xx) -{ - svga_t *svga = &gd54xx->svga; - - if (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&gd54xx->linear_mapping); - mem_mapping_disable(&gd54xx->mmio_mapping); - return; - } - - gd54xx->mmio_vram_overlap = 0; - - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_disable(&gd54xx->linear_mapping); - switch (svga->gdcreg[6] & 0x0c) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - gd54xx->mmio_vram_overlap = 1; - break; - } - if (svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) - mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x00100); - else - mem_mapping_disable(&gd54xx->mmio_mapping); - } else { - uint32_t base, size; - - if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429 || (!gd54xx->pci && !gd54xx->vlb)) { - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) { - base = (svga->seqregs[7] & 0xf0) << 16; - size = 1 * 1024 * 1024; - } else { - base = (svga->seqregs[7] & 0xe0) << 16; - size = 2 * 1024 * 1024; - } - } else if (gd54xx->pci) { - base = gd54xx->lfb_base; - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - size = 16 * 1024 * 1024; - else - size = 4 * 1024 * 1024; - } else { /*VLB*/ - base = 128*1024*1024; - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - size = 16 * 1024 * 1024; - else - size = 4 * 1024 * 1024; - } - - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&gd54xx->linear_mapping, base, size); - if (svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) { - if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) { - if (size >= (4 * 1024 * 1024)) - mem_mapping_disable(&gd54xx->mmio_mapping); /* MMIO is handled in the linear read/write functions */ - else { - mem_mapping_set_addr(&gd54xx->linear_mapping, base, size - 256); - mem_mapping_set_addr(&gd54xx->mmio_mapping, base + size - 256, 0x00100); - } - } else - mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x00100); - } else - mem_mapping_disable(&gd54xx->mmio_mapping); - } -} - - -static void -gd54xx_recalctimings(svga_t *svga) -{ - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - uint8_t clocksel; - - svga->rowoffset = (svga->crtc[0x13]) | ((svga->crtc[0x1b] & 0x10) << 4); - - svga->interlace = (svga->crtc[0x1a] & 0x01); - - if (svga->seqregs[7] & CIRRUS_SR7_BPP_SVGA) - svga->render = svga_render_8bpp_highres; - else if (svga->gdcreg[5] & 0x40) - svga->render = svga_render_8bpp_lowres; - - svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); - - svga->bpp = 8; - - if (gd54xx->ramdac.ctrl & 0x80) { - if (gd54xx->ramdac.ctrl & 0x40) { - switch (gd54xx->ramdac.ctrl & 0xf) { - case 0: - svga->bpp = 15; - svga->render = svga_render_15bpp_highres; - break; - - case 1: - svga->bpp = 16; - svga->render = svga_render_16bpp_highres; - break; - - case 5: - if (gd54xx_is_5434(svga) && (svga->seqregs[7] & CIRRUS_SR7_BPP_32)) { - svga->bpp = 32; - svga->render = svga_render_32bpp_highres; - if (svga->crtc[0x27] < CIRRUS_ID_CLGD5436) - svga->rowoffset *= 2; - } else { - svga->bpp = 24; - svga->render = svga_render_24bpp_highres; - } - break; - - case 0xf: - switch (svga->seqregs[7] & CIRRUS_SR7_BPP_MASK) { - case CIRRUS_SR7_BPP_32: - svga->bpp = 32; - svga->render = svga_render_32bpp_highres; - svga->rowoffset *= 2; - break; - - case CIRRUS_SR7_BPP_24: - svga->bpp = 24; - svga->render = svga_render_24bpp_highres; - break; - - case CIRRUS_SR7_BPP_16: - case CIRRUS_SR7_BPP_16_DOUBLEVCLK: - svga->bpp = 16; - svga->render = svga_render_16bpp_highres; - break; - - case CIRRUS_SR7_BPP_8: - svga->bpp = 8; - svga->render = svga_render_8bpp_highres; - break; - } - break; - } - } else { - svga->bpp = 15; - svga->render = svga_render_15bpp_highres; - } - } - - clocksel = (svga->miscout >> 2) & 3; - - if (!gd54xx->vclk_n[clocksel] || !gd54xx->vclk_d[clocksel]) - svga->clock = cpuclock / ((svga->miscout & 0xc) ? 28322000.0 : 25175000.0); - else { - int n = gd54xx->vclk_n[clocksel] & 0x7f; - int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; - int m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; - float freq = (14318184.0 * ((float)n / ((float)d * m))); - switch (svga->seqregs[7] & (gd54xx_is_5434(svga) ? 0xe : 6)) { - case 2: - freq /= 2.0; - break; - case 4: - if (!gd54xx_is_5434(svga)) - freq /= 3.0; - break; - } - svga->clock = cpuclock / freq; - } - - svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff; -} - -static -void gd54xx_hwcursor_draw(svga_t *svga, int displine) -{ - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - int x, xx, comb, b0, b1; - uint8_t dat[2]; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - int pitch = (svga->hwcursor.xsize == 64) ? 16 : 4; - uint32_t bgcol = gd54xx->extpallook[0x00]; - uint32_t fgcol = gd54xx->extpallook[0x0f]; - - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; - - for (x = 0; x < svga->hwcursor.xsize; x += 8) { - dat[0] = svga->vram[svga->hwcursor_latch.addr]; - if (svga->hwcursor.xsize == 64) - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x08]; - else - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; - for (xx = 0; xx < 8; xx++) { - b0 = (dat[0] >> (7 - xx)) & 1; - b1 = (dat[1] >> (7 - xx)) & 1; - comb = (b1 | (b0 << 1)); - if (offset >= svga->hwcursor_latch.x) { - switch(comb) { - case 0: - /* The original screen pixel is shown (invisible cursor) */ - break; - case 1: - /* The pixel is shown in the cursor background color */ - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = bgcol; - break; - case 2: - /* The pixel is shown as the inverse of the original screen pixel - (XOR cursor) */ - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; - break; - case 3: - /* The pixel is shown in the cursor foreground color */ - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = fgcol; - break; - } - } - - offset++; - } - svga->hwcursor_latch.addr++; - } - - if (svga->hwcursor.xsize == 64) - svga->hwcursor_latch.addr += 8; - - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; -} - -static void -gd54xx_memsrc_rop(gd54xx_t *gd54xx, svga_t *svga, uint8_t src, uint8_t dst) -{ - uint8_t res = src; - svga->changedvram[(gd54xx->blt.dst_addr_backup & svga->vram_mask) >> 12] = changeframecount; - - switch (gd54xx->blt.rop) { - case 0x00: res = 0; break; - case 0x05: res = src & dst; break; - case 0x06: res = dst; break; - case 0x09: res = src & ~dst; break; - case 0x0b: res = ~ dst; break; - case 0x0d: res = src; break; - case 0x0e: res = 0xff; break; - case 0x50: res = ~ src & dst; break; - case 0x59: res = src ^ dst; break; - case 0x6d: res = src | dst; break; - case 0x90: res = ~(src | dst); break; - case 0x95: res = ~(src ^ dst); break; - case 0xad: res = src | ~dst; break; - case 0xd0: res = ~src; break; - case 0xd6: res = ~src | dst; break; - case 0xda: res = ~(src & dst); break; - } - - /* handle transparency compare */ - if(gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { /* TODO: 16-bit compare */ - /* if ROP result matches the transparency colour, don't change the pixel */ - if((res & (~gd54xx->blt.trans_mask & 0xff)) == ((gd54xx->blt.trans_col & 0xff) & (~gd54xx->blt.trans_mask & 0xff))) - return; - } - - svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask] = res; -} - - -/* non colour-expanded BitBLTs from system memory must be doubleword sized, extra bytes are ignored */ -static void -gd54xx_blit_dword(gd54xx_t *gd54xx, svga_t *svga) -{ - /* TODO: add support for reverse direction */ - uint8_t x, pixel; - - for (x=0;x<32;x+=8) { - pixel = ((gd54xx->blt.sys_buf & (0xff << x)) >> x); - if(gd54xx->blt.pixel_cnt <= gd54xx->blt.width) - gd54xx_memsrc_rop(gd54xx, svga, pixel, svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask]); - gd54xx->blt.dst_addr_backup++; - gd54xx->blt.pixel_cnt++; - } - if (gd54xx->blt.pixel_cnt > gd54xx->blt.width) { - gd54xx->blt.pixel_cnt = 0; - gd54xx->blt.scan_cnt++; - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr + (gd54xx->blt.dst_pitch*gd54xx->blt.scan_cnt); - } - if (gd54xx->blt.scan_cnt > gd54xx->blt.height) { - gd54xx->blt.sys_tx = 0; /* BitBLT complete */ - gd543x_recalc_mapping(gd54xx); - } -} - - -static void -gd54xx_blt_write_w(uint32_t addr, uint16_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - gd54xx_start_blit(val, 16, gd54xx, &gd54xx->svga); -} - - -static void -gd54xx_blt_write_l(uint32_t addr, uint32_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) == (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) { - gd54xx_start_blit(val & 0xff, 8, gd54xx, &gd54xx->svga); - gd54xx_start_blit((val>>8) & 0xff, 8, gd54xx, &gd54xx->svga); - gd54xx_start_blit((val>>16) & 0xff, 8, gd54xx, &gd54xx->svga); - gd54xx_start_blit((val>>24) & 0xff, 8, gd54xx, &gd54xx->svga); - } else - gd54xx_start_blit(val, 32, gd54xx, &gd54xx->svga); -} - - -static void -gd54xx_write(uint32_t addr, uint8_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd54xx->blt.sys_tx) { - if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { - gd54xx->blt.sys_buf &= ~(0xff << (gd54xx->blt.sys_cnt * 8)); - gd54xx->blt.sys_buf |= (val << (gd54xx->blt.sys_cnt * 8)); - gd54xx->blt.sys_cnt++; - if(gd54xx->blt.sys_cnt >= 4) { - gd54xx_blit_dword(gd54xx, svga); - gd54xx->blt.sys_cnt = 0; - } - } - return; - } - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - - svga_write_linear(addr, val, svga); -} - - -static void -gd54xx_writew(uint32_t addr, uint16_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd54xx->blt.sys_tx) - { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - return; - } - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - - if (svga->writemode < 4) - svga_writew_linear(addr, val, svga); - else { - svga_write_linear(addr, val, svga); - svga_write_linear(addr + 1, val >> 8, svga); - } -} - - -static void -gd54xx_writel(uint32_t addr, uint32_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd54xx->blt.sys_tx) - { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - gd54xx_write(addr+2, val >> 16, gd54xx); - gd54xx_write(addr+3, val >> 24, gd54xx); - return; - } - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - - if (svga->writemode < 4) - svga_writel_linear(addr, val, svga); - else { - svga_write_linear(addr, val, svga); - svga_write_linear(addr+1, val >> 8, svga); - svga_write_linear(addr+2, val >> 16, svga); - svga_write_linear(addr+3, val >> 24, svga); - } -} - - -/* This adds write modes 4 and 5 to SVGA. */ -static void -gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr) -{ - uint32_t i, j; - - switch (svga->writemode) { - case 4: - if (svga->gdcreg[0xb] & 0x10) { - addr <<= 2; - - for (i = 0; i < 8; i++) { - if (val & svga->seqregs[2] & (0x80 >> i)) { - svga->vram[addr + (i << 1)] = svga->gdcreg[1]; - svga->vram[addr + (i << 1) + 1] = svga->gdcreg[0x11]; - } - } - } else { - addr <<= 1; - - for (i = 0; i < 8; i++) { - if (val & svga->seqregs[2] & (0x80 >> i)) - svga->vram[addr + i] = svga->gdcreg[1]; - } - } - break; - - case 5: - if (svga->gdcreg[0xb] & 0x10) { - addr <<= 2; - - for (i = 0; i < 8; i++) { - j = (0x80 >> i); - if (svga->seqregs[2] & j) { - svga->vram[addr + (i << 1)] = (val & j) ? - svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + (i << 1) + 1] = (val & j) ? - svga->gdcreg[0x11] : svga->gdcreg[0x10]; - } - } - } else { - addr <<= 1; - - for (i = 0; i < 8; i++) { - j = (0x80 >> i); - if (svga->seqregs[2] & j) - svga->vram[addr + i] = (val & j) ? svga->gdcreg[1] : svga->gdcreg[0]; - } - } - break; - } - - svga->changedvram[addr >> 12] = changeframecount; -} - - -static uint8_t -gd54xx_get_aperture(uint32_t addr) -{ - uint32_t ap = addr >> 22; - return (uint8_t) (ap & 0x03); -} - - -static uint8_t -gd54xx_readb_linear(uint32_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - addr &= 0x003fffff; /* 4 MB mask */ - - switch (ap) { - case 0: - default: - break; - case 1: - /* 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2 */ - addr ^= 0x00000001; - break; - case 2: - /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ - addr ^= 0x00000003; - break; - case 3: - return 0xff; - } - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) - return gd543x_mmio_read(addr & 0x000000ff, gd54xx); - } - - return svga_read_linear(addr, p); -} - - -static uint16_t -gd54xx_readw_linear(uint32_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - uint16_t temp, temp2; - - addr &= 0x003fffff; /* 4 MB mask */ - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - if (ap == 2) - addr ^= 0x00000002; - - temp = gd543x_mmio_readw(addr & 0x000000ff, gd54xx); - - switch(ap) { - case 0: - default: - return temp; - case 1: - case 2: - temp2 = temp >> 8; - temp2 |= ((temp & 0xff) << 8); - return temp; - case 3: - return 0xffff; - } - } - } - - switch (ap) { - case 0: - default: - return svga_readw_linear(addr, p); - case 2: - /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ - addr ^= 0x00000002; - case 1: - temp = svga_readb_linear(addr + 1, p); - temp |= (svga_readb_linear(addr, p) << 8); - - if (svga->fast) - cycles -= video_timing_read_w; - - return temp; - case 3: - return 0xffff; - } -} - - -static uint32_t -gd54xx_readl_linear(uint32_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - uint32_t temp, temp2; - - addr &= 0x003fffff; /* 4 MB mask */ - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - temp = gd543x_mmio_readl(addr & 0x000000ff, gd54xx); - - switch(ap) { - case 0: - default: - return temp; - case 1: - temp2 = temp >> 24; - temp2 |= ((temp >> 16) & 0xff) << 8; - temp2 |= ((temp >> 8) & 0xff) << 16; - temp2 |= (temp & 0xff) << 24; - - return temp2; - case 2: - temp2 = (temp >> 8) & 0xff; - temp2 |= (temp & 0xff) << 8; - temp2 = ((temp >> 24) & 0xff) << 16; - temp2 = ((temp >> 16) & 0xff) << 24; - - return temp2; - case 3: - return 0xffffffff; - } - } - } - - switch (ap) { - case 0: - default: - return svga_readw_linear(addr, p); - case 1: - temp = svga_readb_linear(addr + 1, p); - temp |= (svga_readb_linear(addr, p) << 8); - temp |= (svga_readb_linear(addr + 3, p) << 16); - temp |= (svga_readb_linear(addr + 2, p) << 24); - - if (svga->fast) - cycles -= video_timing_read_l; - - return temp; - case 2: - temp = svga_readb_linear(addr + 3, p); - temp |= (svga_readb_linear(addr + 2, p) << 8); - temp |= (svga_readb_linear(addr + 1, p) << 16); - temp |= (svga_readb_linear(addr, p) << 24); - - if (svga->fast) - cycles -= video_timing_read_l; - - return temp; - case 3: - return 0xffffffff; - } -} - - -static void -gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - addr &= 0x003fffff; /* 4 MB mask */ - - switch (ap) { - case 0: - default: - break; - case 1: - /* 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2 */ - addr ^= 0x00000001; - break; - case 2: - /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ - addr ^= 0x00000003; - break; - case 3: - return; - } - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) - gd543x_mmio_write(addr & 0x000000ff, val, gd54xx); - } - - if (gd54xx->blt.sys_tx) { - if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { - gd54xx->blt.sys_buf &= ~(0xff << (gd54xx->blt.sys_cnt * 8)); - gd54xx->blt.sys_buf |= (val << (gd54xx->blt.sys_cnt * 8)); - gd54xx->blt.sys_cnt++; - if(gd54xx->blt.sys_cnt >= 4) { - gd54xx_blit_dword(gd54xx, svga); - gd54xx->blt.sys_cnt = 0; - } - } - return; - } - - svga_write_linear(addr, val, svga); -} - - -static void -gd54xx_writew_linear(uint32_t addr, uint16_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - uint16_t temp; - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - switch(ap) { - case 0: - default: - gd543x_mmio_writew(addr & 0x000000ff, val, gd54xx); - return; - case 2: - addr ^= 0x00000002; - case 1: - temp = (val >> 8); - temp |= ((val & 0xff) << 8); - gd543x_mmio_writew(addr & 0x000000ff, temp, gd54xx); - case 3: - return; - } - } - } - - if (gd54xx->blt.sys_tx) { - gd54xx_writeb_linear(addr, val, svga); - gd54xx_writeb_linear(addr+1, val >> 8, svga); - return; - } - - addr &= 0x003fffff; /* 4 MB mask */ - - if (svga->writemode < 4) { - switch(ap) { - case 0: - default: - svga_writew_linear(addr, val, svga); - return; - case 2: - addr ^= 0x00000002; - case 1: - svga_writeb_linear(addr + 1, val & 0xff, svga); - svga_writeb_linear(addr, val >> 8, svga); - - if (svga->fast) - cycles -= video_timing_write_w; - case 3: - return; - } - } else { - switch(ap) { - case 0: - default: - svga_write_linear(addr, val & 0xff, svga); - svga_write_linear(addr + 1, val >> 8, svga); - return; - case 2: - addr ^= 0x00000002; - case 1: - svga_write_linear(addr + 1, val & 0xff, svga); - svga_write_linear(addr, val >> 8, svga); - case 3: - return; - } - } -} - - -static void -gd54xx_writel_linear(uint32_t addr, uint32_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - - uint8_t ap = gd54xx_get_aperture(addr); - uint32_t temp; - - if ((addr & 0x003fff00) == 0x003fff00) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - switch(ap) { - case 0: - default: - gd543x_mmio_writel(addr & 0x000000ff, val, gd54xx); - return; - case 2: - temp = (val >> 24); - temp |= ((val >> 16) & 0xff) << 8; - temp |= ((val >> 8) & 0xff) << 16; - temp |= (val & 0xff) << 24; - gd543x_mmio_writel(addr & 0x000000ff, temp, gd54xx); - return; - case 1: - temp = ((val >> 8) & 0xff); - temp |= (val & 0xff) << 8; - temp |= (val >> 24) << 16; - temp |= ((val >> 16) & 0xff) << 24; - gd543x_mmio_writel(addr & 0x000000ff, temp, gd54xx); - return; - case 3: - return; - } - } - } - - if (gd54xx->blt.sys_tx) { - gd54xx_writeb_linear(addr, val, svga); - gd54xx_writeb_linear(addr+1, val >> 8, svga); - gd54xx_writeb_linear(addr+2, val >> 16, svga); - gd54xx_writeb_linear(addr+3, val >> 24, svga); - return; - } - - addr &= 0x003fffff; /* 4 MB mask */ - - if (svga->writemode < 4) { - switch(ap) { - case 0: - default: - svga_writel_linear(addr, val, svga); - return; - case 1: - svga_writeb_linear(addr + 1, val & 0xff, svga); - svga_writeb_linear(addr, val >> 8, svga); - svga_writeb_linear(addr + 3, val >> 16, svga); - svga_writeb_linear(addr + 2, val >> 24, svga); - return; - case 2: - svga_writeb_linear(addr + 3, val & 0xff, svga); - svga_writeb_linear(addr + 2, val >> 8, svga); - svga_writeb_linear(addr + 1, val >> 16, svga); - svga_writeb_linear(addr, val >> 24, svga); - case 3: - return; - } - - if (svga->fast) - cycles -= video_timing_write_l; - } else { - switch(ap) { - case 0: - default: - svga_write_linear(addr, val & 0xff, svga); - svga_write_linear(addr+1, val >> 8, svga); - svga_write_linear(addr+2, val >> 16, svga); - svga_write_linear(addr+3, val >> 24, svga); - return; - case 1: - svga_write_linear(addr + 1, val & 0xff, svga); - svga_write_linear(addr, val >> 8, svga); - svga_write_linear(addr + 3, val >> 16, svga); - svga_write_linear(addr + 2, val >> 24, svga); - return; - case 2: - svga_write_linear(addr + 3, val & 0xff, svga); - svga_write_linear(addr + 2, val >> 8, svga); - svga_write_linear(addr + 1, val >> 16, svga); - svga_write_linear(addr, val >> 24, svga); - case 3: - return; - } - } -} - - -static uint8_t -gd54xx_read(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - return svga_read_linear(addr, svga); -} - - -static uint16_t -gd54xx_readw(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - return svga_readw_linear(addr, svga); -} - - -static uint32_t -gd54xx_readl(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd54xx->bank[(addr >> 15) & 1]; - return svga_readl_linear(addr, svga); -} - - -static int -gd543x_do_mmio(svga_t *svga, uint32_t addr) -{ - if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) - return 1; - else - return ((addr & ~0xff) == 0xb8000); -} - - -static void -gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) { - switch (addr & 0xff) { - case 0x00: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xffffff00) | val; - else - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00) | val; - break; - case 0x01: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xffff00ff) | (val << 8); - else - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ff) | (val << 8); - break; - case 0x02: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00ffff) | (val << 16); - break; - case 0x03: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ffffff) | (val << 24); - break; - - case 0x04: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xffffff00) | val; - else - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00) | val; - break; - case 0x05: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xffff00ff) | (val << 8); - else - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ff) | (val << 8); - break; - case 0x06: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00ffff) | (val << 16); - break; - case 0x07: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ffffff) | (val << 24); - break; - - case 0x08: - gd54xx->blt.width = (gd54xx->blt.width & 0xff00) | val; - break; - case 0x09: - gd54xx->blt.width = (gd54xx->blt.width & 0x00ff) | (val << 8); - if (gd54xx_is_5434(svga)) - gd54xx->blt.width &= 0x1fff; - else - gd54xx->blt.width &= 0x07ff; - break; - case 0x0a: - gd54xx->blt.height = (gd54xx->blt.height & 0xff00) | val; - break; - case 0x0b: - gd54xx->blt.height = (gd54xx->blt.height & 0x00ff) | (val << 8); - gd54xx->blt.height &= 0x03ff; - break; - case 0x0c: - gd54xx->blt.dst_pitch = (gd54xx->blt.dst_pitch & 0xff00) | val; - break; - case 0x0d: - gd54xx->blt.dst_pitch = (gd54xx->blt.dst_pitch & 0x00ff) | (val << 8); - break; - case 0x0e: - gd54xx->blt.src_pitch = (gd54xx->blt.src_pitch & 0xff00) | val; - break; - case 0x0f: - gd54xx->blt.src_pitch = (gd54xx->blt.src_pitch & 0x00ff) | (val << 8); - break; - - case 0x10: - gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0xffff00) | val; - break; - case 0x11: - gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0xff00ff) | (val << 8); - break; - case 0x12: - gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0x00ffff) | (val << 16); - if (gd54xx_is_5434(svga)) - gd54xx->blt.dst_addr &= 0x3fffff; - else - gd54xx->blt.dst_addr &= 0x1fffff; - - if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) && (gd54xx->blt.status & CIRRUS_BLT_AUTOSTART)) { - if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { - gd54xx->blt.sys_tx = 1; - gd54xx->blt.sys_cnt = 0; - gd54xx->blt.sys_buf = 0; - gd54xx->blt.pixel_cnt = gd54xx->blt.scan_cnt = 0; - gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; - } else - gd54xx_start_blit(0, -1, gd54xx, svga); - } - break; - - case 0x14: - gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0xffff00) | val; - break; - case 0x15: - gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0xff00ff) | (val << 8); - break; - case 0x16: - gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0x00ffff) | (val << 16); - if (gd54xx_is_5434(svga)) - gd54xx->blt.src_addr &= 0x3fffff; - else - gd54xx->blt.src_addr &= 0x1fffff; - break; - - case 0x17: - gd54xx->blt.mask = val; - break; - case 0x18: - gd54xx->blt.mode = val; - break; - - case 0x1a: - gd54xx->blt.rop = val; - break; - - case 0x1b: - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - gd54xx->blt.modeext = val; - break; - - case 0x1c: - gd54xx->blt.trans_col = (gd54xx->blt.trans_col & 0xff00) | val; - break; - - case 0x1d: - gd54xx->blt.trans_col = (gd54xx->blt.trans_col & 0x00ff) | (val << 8); - break; - - case 0x20: - gd54xx->blt.trans_mask = (gd54xx->blt.trans_mask & 0xff00) | val; - break; - - case 0x21: - gd54xx->blt.trans_mask = (gd54xx->blt.trans_mask & 0x00ff) | (val << 8); - break; - - case 0x40: - gd54xx->blt.status = val; - if (gd54xx->blt.status & CIRRUS_BLT_START) { - if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { - gd54xx->blt.sys_tx = 1; - gd54xx->blt.sys_cnt = 0; - gd54xx->blt.sys_buf = 0; - gd54xx->blt.pixel_cnt = gd54xx->blt.scan_cnt = 0; - gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; - } else - gd54xx_start_blit(0, -1, gd54xx, svga); - } - break; - } - } else if (gd54xx->mmio_vram_overlap) - gd54xx_write(addr, val, gd54xx); -} - - -static void -gd543x_mmio_writew(uint32_t addr, uint16_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) { - gd543x_mmio_write(addr, val & 0xff, gd54xx); - gd543x_mmio_write(addr+1, val >> 8, gd54xx); - } else if (gd54xx->mmio_vram_overlap) { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - } -} - - -static void -gd543x_mmio_writel(uint32_t addr, uint32_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) { - gd543x_mmio_write(addr, val & 0xff, gd54xx); - gd543x_mmio_write(addr+1, val >> 8, gd54xx); - gd543x_mmio_write(addr+2, val >> 16, gd54xx); - gd543x_mmio_write(addr+3, val >> 24, gd54xx); - } else if (gd54xx->mmio_vram_overlap) { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - gd54xx_write(addr+2, val >> 16, gd54xx); - gd54xx_write(addr+3, val >> 24, gd54xx); - } -} - - -static uint8_t -gd543x_mmio_read(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) { - switch (addr & 0xff) { - case 0x40: /*BLT status*/ - return 0; - } - return 0xff; /*All other registers read-only*/ - } - else if (gd54xx->mmio_vram_overlap) - return gd54xx_read(addr, gd54xx); - return 0xff; -} - - -static uint16_t -gd543x_mmio_readw(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) - return gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr+1, gd54xx) << 8); - else if (gd54xx->mmio_vram_overlap) - return gd54xx_read(addr, gd54xx) | (gd54xx_read(addr+1, gd54xx) << 8); - return 0xffff; -} - - -static uint32_t -gd543x_mmio_readl(uint32_t addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if (gd543x_do_mmio(svga, addr)) - return gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr+1, gd54xx) << 8) | (gd543x_mmio_read(addr+2, gd54xx) << 16) | (gd543x_mmio_read(addr+3, gd54xx) << 24); - else if (gd54xx->mmio_vram_overlap) - return gd54xx_read(addr, gd54xx) | (gd54xx_read(addr+1, gd54xx) << 8) | (gd54xx_read(addr+2, gd54xx) << 16) | (gd54xx_read(addr+3, gd54xx) << 24); - return 0xffffffff; -} - - -static void -gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) -{ - int blt_mask = 0; - int x_max = 0; - - int shift = 0, last_x = 0; - - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - blt_mask = gd54xx->blt.mask & 7; - x_max = 8; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - blt_mask = gd54xx->blt.mask & 7; - x_max = 16; - blt_mask *= 2; - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - blt_mask = (gd54xx->blt.mask & 0x1f); - x_max = 24; - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - blt_mask = gd54xx->blt.mask & 7; - x_max = 32; - blt_mask *= 4; - break; - } - - last_x = (x_max >> 3) - 1; - - if (count == -1) { - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; - gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; - gd54xx->blt.width_backup = gd54xx->blt.width; - gd54xx->blt.height_internal = gd54xx->blt.height; - gd54xx->blt.x_count = 0; - if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) == (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) - gd54xx->blt.y_count = gd54xx->blt.src_addr & 7; - else - gd54xx->blt.y_count = 0; - - if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) == (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) { - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_set_handler(&svga->mapping, NULL, NULL, NULL, NULL, gd54xx_blt_write_w, gd54xx_blt_write_l); - mem_mapping_set_p(&svga->mapping, gd54xx); - } else { - mem_mapping_set_handler(&gd54xx->linear_mapping, NULL, NULL, NULL, NULL, gd54xx_blt_write_w, gd54xx_blt_write_l); - mem_mapping_set_p(&gd54xx->linear_mapping, gd54xx); - } - gd543x_recalc_mapping(gd54xx); - return; - } else if (gd54xx->blt.mode != CIRRUS_BLTMODE_MEMSYSSRC) { - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); - mem_mapping_set_p(&gd54xx->svga.mapping, gd54xx); - } else { - mem_mapping_set_handler(&gd54xx->linear_mapping, svga_readb_linear, svga_readw_linear, svga_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear); - mem_mapping_set_p(&gd54xx->linear_mapping, svga); - } - gd543x_recalc_mapping(gd54xx); - } - } else if (gd54xx->blt.height_internal == 0xffff) - return; - - while (count) { - uint8_t src = 0, dst; - int mask = 0; - - if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) { - if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY) - mask = (cpu_dat >> 31); - else - mask = cpu_dat & 0x80; - - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; - shift = 0; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - shift = (gd54xx->blt.x_count & 1); - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - shift = (gd54xx->blt.x_count % 3); - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - shift = (gd54xx->blt.x_count & 3); - break; - } - - src = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); - - if (shift == last_x) { - cpu_dat <<= 1; - count--; - } - } - } else { - switch (gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) { - case 0x00: - src = svga->vram[gd54xx->blt.src_addr & svga->vram_mask]; - gd54xx->blt.src_addr += ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -1 : 1); - mask = 1; - break; - case CIRRUS_BLTMODE_PATTERNCOPY: - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~7)) + (gd54xx->blt.y_count << 3) + (gd54xx->blt.x_count & 7)]; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~15)) + (gd54xx->blt.y_count << 4) + (gd54xx->blt.x_count & 15)]; - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~31)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count % 24)]; - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~31)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count & 31)]; - break; - } - mask = 1; - break; - case CIRRUS_BLTMODE_COLOREXPAND: - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> gd54xx->blt.x_count); - shift = 0; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count >> 1)); - shift = (gd54xx->blt.dst_addr & 1); - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count / 3)); - shift = (gd54xx->blt.dst_addr % 3); - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count >> 2)); - shift = (gd54xx->blt.dst_addr & 3); - break; - } - src = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); - break; - case CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND: - if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) { - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - shift = 0; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - shift = (gd54xx->blt.dst_addr & 1); - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - shift = (gd54xx->blt.dst_addr % 3); - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - shift = (gd54xx->blt.dst_addr & 3); - break; - } - src = (gd54xx->blt.fg_col >> (shift << 3)); - } else { - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> gd54xx->blt.x_count); - shift = 0; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count >> 1)); - shift = (gd54xx->blt.dst_addr & 1); - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count / 3)); - shift = (gd54xx->blt.dst_addr % 3); - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count >> 2)); - shift = (gd54xx->blt.dst_addr & 3); - break; - } - - src = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); - } - break; - } - count--; - } - dst = svga->vram[gd54xx->blt.dst_addr & svga->vram_mask]; - svga->changedvram[(gd54xx->blt.dst_addr & svga->vram_mask) >> 12] = changeframecount; - - switch (gd54xx->blt.rop) { - case 0x00: dst = 0; break; - case 0x05: dst = src & dst; break; - case 0x06: dst = dst; break; - case 0x09: dst = src & ~dst; break; - case 0x0b: dst = ~ dst; break; - case 0x0d: dst = src; break; - case 0x0e: dst = 0xff; break; - case 0x50: dst = ~ src & dst; break; - case 0x59: dst = src ^ dst; break; - case 0x6d: dst = src | dst; break; - case 0x90: dst = ~(src | dst); break; - case 0x95: dst = ~(src ^ dst); break; - case 0xad: dst = src | ~dst; break; - case 0xd0: dst = ~src; break; - case 0xd6: dst = ~src | dst; break; - case 0xda: dst = ~(src & dst); break; - } - - if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { - if ((gd54xx->blt.width_backup - gd54xx->blt.width) >= blt_mask && - !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && mask)) - svga->vram[gd54xx->blt.dst_addr & svga->vram_mask] = dst; - } else { - if ((gd54xx->blt.width_backup - gd54xx->blt.width) >= blt_mask && - !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !mask)) - svga->vram[gd54xx->blt.dst_addr & svga->vram_mask] = dst; - } - - gd54xx->blt.dst_addr += ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -1 : 1); - - gd54xx->blt.x_count++; - - if (gd54xx->blt.x_count == x_max) { - gd54xx->blt.x_count = 0; - if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) == CIRRUS_BLTMODE_COLOREXPAND) - gd54xx->blt.src_addr++; - } - - gd54xx->blt.width--; - - if (gd54xx->blt.width == 0xffff) { - gd54xx->blt.width = gd54xx->blt.width_backup; - - gd54xx->blt.dst_addr = gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr_backup + ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -gd54xx->blt.dst_pitch : gd54xx->blt.dst_pitch); - - switch (gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) { - case 0x00: - gd54xx->blt.src_addr = gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr_backup + ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) ? -gd54xx->blt.src_pitch : gd54xx->blt.src_pitch); - break; - case CIRRUS_BLTMODE_COLOREXPAND: - if (gd54xx->blt.x_count != 0) - gd54xx->blt.src_addr++; - break; - } - - gd54xx->blt.x_count = 0; - if (gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) - gd54xx->blt.y_count = (gd54xx->blt.y_count - 1) & 7; - else - gd54xx->blt.y_count = (gd54xx->blt.y_count + 1) & 7; - - gd54xx->blt.height_internal--; - if (gd54xx->blt.height_internal == 0xffff) { - if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) { - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); - mem_mapping_set_p(&svga->mapping, gd54xx); - } else { - mem_mapping_set_handler(&gd54xx->linear_mapping, svga_readb_linear, svga_readw_linear, svga_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear); - mem_mapping_set_p(&gd54xx->linear_mapping, svga); - } - gd543x_recalc_mapping(gd54xx); - } - return; - } - - if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) - return; - } - } -} - - -static uint8_t -cl_pci_read(int func, int addr, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - - if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) - return 0; - - switch (addr) { - case 0x00: return 0x13; /*Cirrus Logic*/ - case 0x01: return 0x10; - - case 0x02: - return svga->crtc[0x27]; - case 0x03: return 0x00; - - case PCI_REG_COMMAND: - return gd54xx->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - - // case 0x07: return 0 << 1; /*Fast DEVSEL timing*/ - case 0x07: return 0x02; /*Fast DEVSEL timing*/ - - case 0x08: return gd54xx->rev; /*Revision ID*/ - case 0x09: return 0x00; /*Programming interface*/ - - case 0x0a: return 0x00; /*Supports VGA interface*/ - case 0x0b: return 0x03; - - case 0x10: return 0x08; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: return 0x00; - case 0x13: return gd54xx->lfb_base >> 24; - - case 0x30: return (gd54xx->pci_regs[0x30] & 0x01); /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return gd54xx->pci_regs[0x32]; - case 0x33: return gd54xx->pci_regs[0x33]; - - case 0x3c: return gd54xx->int_line; - case 0x3d: return PCI_INTA; - } - return 0; -} - - -static void -cl_pci_write(int func, int addr, uint8_t val, void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) - return; - - switch (addr) { - case PCI_REG_COMMAND: - gd54xx->pci_regs[PCI_REG_COMMAND] = val & 0x23; - io_removehandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - if (val & PCI_COMMAND_IO) - io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - gd543x_recalc_mapping(gd54xx); - break; - - case 0x13: - gd54xx->lfb_base = val << 24; - gd543x_recalc_mapping(gd54xx); - break; - - case 0x30: case 0x32: case 0x33: - gd54xx->pci_regs[addr] = val; - if (gd54xx->pci_regs[0x30] & 0x01) { - uint32_t addr = (gd54xx->pci_regs[0x32] << 16) | (gd54xx->pci_regs[0x33] << 24); - mem_mapping_set_addr(&gd54xx->bios_rom.mapping, addr, 0x8000); - } else - mem_mapping_disable(&gd54xx->bios_rom.mapping); - return; - - case 0x3c: - gd54xx->int_line = val; - return; - } -} - - -static void -*gd54xx_init(const device_t *info) -{ - gd54xx_t *gd54xx = malloc(sizeof(gd54xx_t)); - svga_t *svga = &gd54xx->svga; - int id = info->local & 0xff; - wchar_t *romfn = NULL; - memset(gd54xx, 0, sizeof(gd54xx_t)); - - gd54xx->pci = !!(info->flags & DEVICE_PCI); - gd54xx->vlb = !!(info->flags & DEVICE_VLB); - - gd54xx->rev = 0; - gd54xx->has_bios = 1; - switch (id) { - case CIRRUS_ID_CLGD5426: - romfn = BIOS_GD5426_PATH; - break; - - case CIRRUS_ID_CLGD5428: - if (gd54xx->vlb) - romfn = BIOS_GD5428_PATH; - else - romfn = BIOS_GD5428_ISA_PATH; - break; - - case CIRRUS_ID_CLGD5429: - romfn = BIOS_GD5429_PATH; - break; - - case CIRRUS_ID_CLGD5434: - romfn = BIOS_GD5434_PATH; - break; - - case CIRRUS_ID_CLGD5436: - romfn = BIOS_GD5436_PATH; - break; - - case CIRRUS_ID_CLGD5430: - if (info->local & 0x400) { - /* CL-GD 5440 */ - gd54xx->rev = 0x47; - if (info->local & 0x200) { - romfn = NULL; - gd54xx->has_bios = 0; - } else - romfn = BIOS_GD5440_PATH; - } else { - /* CL-GD 5430 */ - if (gd54xx->pci) - romfn = BIOS_GD5430_PCI_PATH; - else - romfn = BIOS_GD5430_VLB_PATH; - } - break; - - case CIRRUS_ID_CLGD5446: - if (info->local & 0x100) - romfn = BIOS_GD5446_STB_PATH; - else - romfn = BIOS_GD5446_PATH; - break; - - case CIRRUS_ID_CLGD5480: - romfn = BIOS_GD5480_PATH; - break; - } - - gd54xx->vram_size = device_get_config_int("memory"); - gd54xx->vram_mask = (gd54xx->vram_size << 20) - 1; - - if (romfn) - rom_init(&gd54xx->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - svga_init(&gd54xx->svga, gd54xx, gd54xx->vram_size << 20, - gd54xx_recalctimings, gd54xx_in, gd54xx_out, - gd54xx_hwcursor_draw, NULL); - svga_set_ven_write(&gd54xx->svga, gd54xx_write_modes45); - - mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); - mem_mapping_set_p(&svga->mapping, gd54xx); - - mem_mapping_add(&gd54xx->mmio_mapping, 0, 0, gd543x_mmio_read, gd543x_mmio_readw, gd543x_mmio_readl, gd543x_mmio_write, gd543x_mmio_writew, gd543x_mmio_writel, NULL, 0, gd54xx); - mem_mapping_add(&gd54xx->linear_mapping, 0, 0, gd54xx_readb_linear, gd54xx_readw_linear, gd54xx_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear, NULL, 0, svga); - - io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - - svga->hwcursor.yoff = 32; - svga->hwcursor.xoff = 0; - - gd54xx->vclk_n[0] = 0x4a; - gd54xx->vclk_d[0] = 0x2b; - gd54xx->vclk_n[1] = 0x5b; - gd54xx->vclk_d[1] = 0x2f; - - gd54xx->bank[1] = 0x8000; - - if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430) - pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx); - - gd54xx->pci_regs[PCI_REG_COMMAND] = 7; - - gd54xx->pci_regs[0x30] = 0x00; - gd54xx->pci_regs[0x32] = 0x0c; - gd54xx->pci_regs[0x33] = 0x00; - - svga->crtc[0x27] = id; - - return gd54xx; -} - -static int -gd5426_available(void) -{ - return rom_present(BIOS_GD5426_PATH); -} - -static int -gd5428_available(void) -{ - return rom_present(BIOS_GD5428_PATH); -} - -static int -gd5428_isa_available(void) -{ - return rom_present(BIOS_GD5428_ISA_PATH); -} - -static int -gd5429_available(void) -{ - return rom_present(BIOS_GD5429_PATH); -} - -static int -gd5430_vlb_available(void) -{ - return rom_present(BIOS_GD5430_VLB_PATH); -} - -static int -gd5430_pci_available(void) -{ - return rom_present(BIOS_GD5430_PCI_PATH); -} - -static int -gd5434_available(void) -{ - return rom_present(BIOS_GD5434_PATH); -} - -static int -gd5436_available(void) -{ - return rom_present(BIOS_GD5436_PATH); -} - -static int -gd5440_available(void) -{ - return rom_present(BIOS_GD5440_PATH); -} - -static int -gd5446_available(void) -{ - return rom_present(BIOS_GD5446_PATH); -} - -static int -gd5446_stb_available(void) -{ - return rom_present(BIOS_GD5446_STB_PATH); -} - -static int -gd5480_available(void) -{ - return rom_present(BIOS_GD5480_PATH); -} - -void -gd54xx_close(void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - svga_close(&gd54xx->svga); - - free(gd54xx); -} - - -void -gd54xx_speed_changed(void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - svga_recalctimings(&gd54xx->svga); -} - - -void -gd54xx_force_redraw(void *p) -{ - gd54xx_t *gd54xx = (gd54xx_t *)p; - - gd54xx->svga.fullchange = changeframecount; -} - - -static const device_config_t gd5428_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } -}; - -static const device_config_t gd5440_onboard_config[] = -{ - { - .name = "memory", - .description = "Video memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } -}; - -static const device_config_t gd5434_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } -}; - -const device_t gd5426_vlb_device = -{ - "Cirrus Logic CL-GD 5426 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5426, - gd54xx_init, - gd54xx_close, - NULL, - gd5426_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5428_isa_device = -{ - "Cirrus Logic CL-GD 5428 (ISA)", - DEVICE_AT | DEVICE_ISA, - CIRRUS_ID_CLGD5428, - gd54xx_init, - gd54xx_close, - NULL, - gd5428_isa_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5428_vlb_device = -{ - "Cirrus Logic CL-GD 5428 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5428, - gd54xx_init, - gd54xx_close, - NULL, - gd5428_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5429_isa_device = -{ - "Cirrus Logic CL-GD 5429 (ISA)", - DEVICE_AT | DEVICE_ISA, - CIRRUS_ID_CLGD5429, - gd54xx_init, - gd54xx_close, - NULL, - gd5429_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5429_vlb_device = -{ - "Cirrus Logic CL-GD 5429 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5429, - gd54xx_init, - gd54xx_close, - NULL, - gd5429_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5430_vlb_device = -{ - "Cirrus Logic CL-GD 5430 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5430, - gd54xx_init, - gd54xx_close, - NULL, - gd5430_vlb_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5430_pci_device = -{ - "Cirrus Logic CL-GD 5430 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5430, - gd54xx_init, - gd54xx_close, - NULL, - gd5430_pci_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5434_isa_device = -{ - "Cirrus Logic CL-GD 5434 (ISA)", - DEVICE_AT | DEVICE_ISA, - CIRRUS_ID_CLGD5434, - gd54xx_init, - gd54xx_close, - NULL, - gd5434_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5434_vlb_device = -{ - "Cirrus Logic CL-GD 5434 (VLB)", - DEVICE_VLB, - CIRRUS_ID_CLGD5434, - gd54xx_init, - gd54xx_close, - NULL, - gd5434_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5434_pci_device = -{ - "Cirrus Logic CL-GD 5434 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5434, - gd54xx_init, - gd54xx_close, - NULL, - gd5434_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5436_pci_device = -{ - "Cirrus Logic CL-GD 5436 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5436, - gd54xx_init, - gd54xx_close, - NULL, - gd5436_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5440_onboard_pci_device = -{ - "Cirrus Logic CL-GD 5440 (On-Board PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5440 | 0x600, - gd54xx_init, - gd54xx_close, - NULL, - NULL, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5440_onboard_config -}; - -const device_t gd5440_pci_device = -{ - "Cirrus Logic CL-GD 5440 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5440 | 0x400, - gd54xx_init, - gd54xx_close, - NULL, - gd5440_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5428_config -}; - -const device_t gd5446_pci_device = -{ - "Cirrus Logic CL-GD 5446 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5446, - gd54xx_init, - gd54xx_close, - NULL, - gd5446_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5446_stb_pci_device = -{ - "STB Nitro 64V (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5446 | 0x100, - gd54xx_init, - gd54xx_close, - NULL, - gd5446_stb_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; - -const device_t gd5480_pci_device = -{ - "Cirrus Logic CL-GD 5480 (PCI)", - DEVICE_PCI, - CIRRUS_ID_CLGD5480, - gd54xx_init, - gd54xx_close, - NULL, - gd5480_available, - gd54xx_speed_changed, - gd54xx_force_redraw, - gd5434_config -}; diff --git a/backup code/video/vid_svga_render - Cópia.c b/backup code/video/vid_svga_render - Cópia.c deleted file mode 100644 index b665012b4..000000000 --- a/backup code/video/vid_svga_render - Cópia.c +++ /dev/null @@ -1,967 +0,0 @@ -/* - * 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. - * - * SVGA renderers. - * - * Version: @(#)vid_svga_render.c 1.0.11 2018/05/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../mem.h" -#include "video.h" -#include "vid_svga.h" -#include "vid_svga_render.h" - - -int invert_display = 0; -int video_grayscale = 0; -int video_graytype = 0; - - -uint32_t shade[5][256] = -{ - {0}, // RGB Color (unused) - {0}, // RGB Grayscale (unused) - { // Amber monitor - 0x000000, 0x060000, 0x090000, 0x0d0000, 0x100000, 0x120100, 0x150100, 0x170100, 0x1a0100, 0x1c0100, 0x1e0200, 0x210200, 0x230200, 0x250300, 0x270300, 0x290300, - 0x2b0400, 0x2d0400, 0x2f0400, 0x300500, 0x320500, 0x340500, 0x360600, 0x380600, 0x390700, 0x3b0700, 0x3d0700, 0x3f0800, 0x400800, 0x420900, 0x440900, 0x450a00, - 0x470a00, 0x480b00, 0x4a0b00, 0x4c0c00, 0x4d0c00, 0x4f0d00, 0x500d00, 0x520e00, 0x530e00, 0x550f00, 0x560f00, 0x581000, 0x591000, 0x5b1100, 0x5c1200, 0x5e1200, - 0x5f1300, 0x601300, 0x621400, 0x631500, 0x651500, 0x661600, 0x671600, 0x691700, 0x6a1800, 0x6c1800, 0x6d1900, 0x6e1a00, 0x701a00, 0x711b00, 0x721c00, 0x741c00, - 0x751d00, 0x761e00, 0x781e00, 0x791f00, 0x7a2000, 0x7c2000, 0x7d2100, 0x7e2200, 0x7f2300, 0x812300, 0x822400, 0x832500, 0x842600, 0x862600, 0x872700, 0x882800, - 0x8a2900, 0x8b2900, 0x8c2a00, 0x8d2b00, 0x8e2c00, 0x902c00, 0x912d00, 0x922e00, 0x932f00, 0x953000, 0x963000, 0x973100, 0x983200, 0x993300, 0x9b3400, 0x9c3400, - 0x9d3500, 0x9e3600, 0x9f3700, 0xa03800, 0xa23900, 0xa33a00, 0xa43a00, 0xa53b00, 0xa63c00, 0xa73d00, 0xa93e00, 0xaa3f00, 0xab4000, 0xac4000, 0xad4100, 0xae4200, - 0xaf4300, 0xb14400, 0xb24500, 0xb34600, 0xb44700, 0xb54800, 0xb64900, 0xb74a00, 0xb94a00, 0xba4b00, 0xbb4c00, 0xbc4d00, 0xbd4e00, 0xbe4f00, 0xbf5000, 0xc05100, - 0xc15200, 0xc25300, 0xc45400, 0xc55500, 0xc65600, 0xc75700, 0xc85800, 0xc95900, 0xca5a00, 0xcb5b00, 0xcc5c00, 0xcd5d00, 0xce5e00, 0xcf5f00, 0xd06000, 0xd26101, - 0xd36201, 0xd46301, 0xd56401, 0xd66501, 0xd76601, 0xd86701, 0xd96801, 0xda6901, 0xdb6a01, 0xdc6b01, 0xdd6c01, 0xde6d01, 0xdf6e01, 0xe06f01, 0xe17001, 0xe27201, - 0xe37301, 0xe47401, 0xe57501, 0xe67602, 0xe77702, 0xe87802, 0xe97902, 0xeb7a02, 0xec7b02, 0xed7c02, 0xee7e02, 0xef7f02, 0xf08002, 0xf18103, 0xf28203, 0xf38303, - 0xf48403, 0xf58503, 0xf68703, 0xf78803, 0xf88903, 0xf98a04, 0xfa8b04, 0xfb8c04, 0xfc8d04, 0xfd8f04, 0xfe9005, 0xff9105, 0xff9205, 0xff9305, 0xff9405, 0xff9606, - 0xff9706, 0xff9806, 0xff9906, 0xff9a07, 0xff9b07, 0xff9d07, 0xff9e08, 0xff9f08, 0xffa008, 0xffa109, 0xffa309, 0xffa409, 0xffa50a, 0xffa60a, 0xffa80a, 0xffa90b, - 0xffaa0b, 0xffab0c, 0xffac0c, 0xffae0d, 0xffaf0d, 0xffb00e, 0xffb10e, 0xffb30f, 0xffb40f, 0xffb510, 0xffb610, 0xffb811, 0xffb912, 0xffba12, 0xffbb13, 0xffbd14, - 0xffbe14, 0xffbf15, 0xffc016, 0xffc217, 0xffc317, 0xffc418, 0xffc619, 0xffc71a, 0xffc81b, 0xffca1c, 0xffcb1d, 0xffcc1e, 0xffcd1f, 0xffcf20, 0xffd021, 0xffd122, - 0xffd323, 0xffd424, 0xffd526, 0xffd727, 0xffd828, 0xffd92a, 0xffdb2b, 0xffdc2c, 0xffdd2e, 0xffdf2f, 0xffe031, 0xffe133, 0xffe334, 0xffe436, 0xffe538, 0xffe739 - }, - { // Green monitor - 0x000000, 0x000400, 0x000700, 0x000900, 0x000b00, 0x000d00, 0x000f00, 0x001100, 0x001300, 0x001500, 0x001600, 0x001800, 0x001a00, 0x001b00, 0x001d00, 0x001e00, - 0x002000, 0x002100, 0x002300, 0x002400, 0x002601, 0x002701, 0x002901, 0x002a01, 0x002b01, 0x002d01, 0x002e01, 0x002f01, 0x003101, 0x003201, 0x003301, 0x003401, - 0x003601, 0x003702, 0x003802, 0x003902, 0x003b02, 0x003c02, 0x003d02, 0x003e02, 0x004002, 0x004102, 0x004203, 0x004303, 0x004403, 0x004503, 0x004703, 0x004803, - 0x004903, 0x004a03, 0x004b04, 0x004c04, 0x004d04, 0x004e04, 0x005004, 0x005104, 0x005205, 0x005305, 0x005405, 0x005505, 0x005605, 0x005705, 0x005806, 0x005906, - 0x005a06, 0x005b06, 0x005d06, 0x005e07, 0x005f07, 0x006007, 0x006107, 0x006207, 0x006308, 0x006408, 0x006508, 0x006608, 0x006708, 0x006809, 0x006909, 0x006a09, - 0x006b09, 0x016c0a, 0x016d0a, 0x016e0a, 0x016f0a, 0x01700b, 0x01710b, 0x01720b, 0x01730b, 0x01740c, 0x01750c, 0x01760c, 0x01770c, 0x01780d, 0x01790d, 0x017a0d, - 0x017b0d, 0x017b0e, 0x017c0e, 0x017d0e, 0x017e0f, 0x017f0f, 0x01800f, 0x018110, 0x028210, 0x028310, 0x028410, 0x028511, 0x028611, 0x028711, 0x028812, 0x028912, - 0x028a12, 0x028a13, 0x028b13, 0x028c13, 0x028d14, 0x028e14, 0x038f14, 0x039015, 0x039115, 0x039215, 0x039316, 0x039416, 0x039417, 0x039517, 0x039617, 0x039718, - 0x049818, 0x049918, 0x049a19, 0x049b19, 0x049c19, 0x049c1a, 0x049d1a, 0x049e1b, 0x059f1b, 0x05a01b, 0x05a11c, 0x05a21c, 0x05a31c, 0x05a31d, 0x05a41d, 0x06a51e, - 0x06a61e, 0x06a71f, 0x06a81f, 0x06a920, 0x06aa20, 0x07aa21, 0x07ab21, 0x07ac21, 0x07ad22, 0x07ae22, 0x08af23, 0x08b023, 0x08b024, 0x08b124, 0x08b225, 0x09b325, - 0x09b426, 0x09b526, 0x09b527, 0x0ab627, 0x0ab728, 0x0ab828, 0x0ab929, 0x0bba29, 0x0bba2a, 0x0bbb2a, 0x0bbc2b, 0x0cbd2b, 0x0cbe2c, 0x0cbf2c, 0x0dbf2d, 0x0dc02d, - 0x0dc12e, 0x0ec22e, 0x0ec32f, 0x0ec42f, 0x0fc430, 0x0fc530, 0x0fc631, 0x10c731, 0x10c832, 0x10c932, 0x11c933, 0x11ca33, 0x11cb34, 0x12cc35, 0x12cd35, 0x12cd36, - 0x13ce36, 0x13cf37, 0x13d037, 0x14d138, 0x14d139, 0x14d239, 0x15d33a, 0x15d43a, 0x16d43b, 0x16d53b, 0x17d63c, 0x17d73d, 0x17d83d, 0x18d83e, 0x18d93e, 0x19da3f, - 0x19db40, 0x1adc40, 0x1adc41, 0x1bdd41, 0x1bde42, 0x1cdf43, 0x1ce043, 0x1de044, 0x1ee145, 0x1ee245, 0x1fe346, 0x1fe446, 0x20e447, 0x20e548, 0x21e648, 0x22e749, - 0x22e74a, 0x23e84a, 0x23e94b, 0x24ea4c, 0x25ea4c, 0x25eb4d, 0x26ec4e, 0x27ed4e, 0x27ee4f, 0x28ee50, 0x29ef50, 0x29f051, 0x2af152, 0x2bf153, 0x2cf253, 0x2cf354, - 0x2df455, 0x2ef455, 0x2ff556, 0x2ff657, 0x30f758, 0x31f758, 0x32f859, 0x32f95a, 0x33fa5a, 0x34fa5b, 0x35fb5c, 0x36fc5d, 0x37fd5d, 0x38fd5e, 0x38fe5f, 0x39ff60 - }, - { // White monitor - 0x000000, 0x010102, 0x020203, 0x020304, 0x030406, 0x040507, 0x050608, 0x060709, 0x07080a, 0x08090c, 0x080a0d, 0x090b0e, 0x0a0c0f, 0x0b0d10, 0x0c0e11, 0x0d0f12, - 0x0e1013, 0x0f1115, 0x101216, 0x111317, 0x121418, 0x121519, 0x13161a, 0x14171b, 0x15181c, 0x16191d, 0x171a1e, 0x181b1f, 0x191c20, 0x1a1d21, 0x1b1e22, 0x1c1f23, - 0x1d2024, 0x1e2125, 0x1f2226, 0x202327, 0x212428, 0x222529, 0x22262b, 0x23272c, 0x24282d, 0x25292e, 0x262a2f, 0x272b30, 0x282c30, 0x292d31, 0x2a2e32, 0x2b2f33, - 0x2c3034, 0x2d3035, 0x2e3136, 0x2f3237, 0x303338, 0x313439, 0x32353a, 0x33363b, 0x34373c, 0x35383d, 0x36393e, 0x373a3f, 0x383b40, 0x393c41, 0x3a3d42, 0x3b3e43, - 0x3c3f44, 0x3d4045, 0x3e4146, 0x3f4247, 0x404348, 0x414449, 0x42454a, 0x43464b, 0x44474c, 0x45484d, 0x46494d, 0x474a4e, 0x484b4f, 0x484c50, 0x494d51, 0x4a4e52, - 0x4b4f53, 0x4c5054, 0x4d5155, 0x4e5256, 0x4f5357, 0x505458, 0x515559, 0x52565a, 0x53575b, 0x54585b, 0x55595c, 0x565a5d, 0x575b5e, 0x585c5f, 0x595d60, 0x5a5e61, - 0x5b5f62, 0x5c6063, 0x5d6164, 0x5e6265, 0x5f6366, 0x606466, 0x616567, 0x626668, 0x636769, 0x64686a, 0x65696b, 0x666a6c, 0x676b6d, 0x686c6e, 0x696d6f, 0x6a6e70, - 0x6b6f70, 0x6c7071, 0x6d7172, 0x6f7273, 0x707374, 0x707475, 0x717576, 0x727677, 0x747778, 0x757879, 0x767979, 0x777a7a, 0x787b7b, 0x797c7c, 0x7a7d7d, 0x7b7e7e, - 0x7c7f7f, 0x7d8080, 0x7e8181, 0x7f8281, 0x808382, 0x818483, 0x828584, 0x838685, 0x848786, 0x858887, 0x868988, 0x878a89, 0x888b89, 0x898c8a, 0x8a8d8b, 0x8b8e8c, - 0x8c8f8d, 0x8d8f8e, 0x8e908f, 0x8f9190, 0x909290, 0x919391, 0x929492, 0x939593, 0x949694, 0x959795, 0x969896, 0x979997, 0x989a98, 0x999b98, 0x9a9c99, 0x9b9d9a, - 0x9c9e9b, 0x9d9f9c, 0x9ea09d, 0x9fa19e, 0xa0a29f, 0xa1a39f, 0xa2a4a0, 0xa3a5a1, 0xa4a6a2, 0xa6a7a3, 0xa7a8a4, 0xa8a9a5, 0xa9aaa5, 0xaaaba6, 0xabaca7, 0xacada8, - 0xadaea9, 0xaeafaa, 0xafb0ab, 0xb0b1ac, 0xb1b2ac, 0xb2b3ad, 0xb3b4ae, 0xb4b5af, 0xb5b6b0, 0xb6b7b1, 0xb7b8b2, 0xb8b9b2, 0xb9bab3, 0xbabbb4, 0xbbbcb5, 0xbcbdb6, - 0xbdbeb7, 0xbebfb8, 0xbfc0b8, 0xc0c1b9, 0xc1c2ba, 0xc2c3bb, 0xc3c4bc, 0xc5c5bd, 0xc6c6be, 0xc7c7be, 0xc8c8bf, 0xc9c9c0, 0xcacac1, 0xcbcbc2, 0xccccc3, 0xcdcdc3, - 0xcecec4, 0xcfcfc5, 0xd0d0c6, 0xd1d1c7, 0xd2d2c8, 0xd3d3c9, 0xd4d4c9, 0xd5d5ca, 0xd6d6cb, 0xd7d7cc, 0xd8d8cd, 0xd9d9ce, 0xdadacf, 0xdbdbcf, 0xdcdcd0, 0xdeddd1, - 0xdfded2, 0xe0dfd3, 0xe1e0d4, 0xe2e1d4, 0xe3e2d5, 0xe4e3d6, 0xe5e4d7, 0xe6e5d8, 0xe7e6d9, 0xe8e7d9, 0xe9e8da, 0xeae9db, 0xebeadc, 0xecebdd, 0xedecde, 0xeeeddf, - 0xefeedf, 0xf0efe0, 0xf1f0e1, 0xf2f1e2, 0xf3f2e3, 0xf4f3e3, 0xf6f3e4, 0xf7f4e5, 0xf8f5e6, 0xf9f6e7, 0xfaf7e8, 0xfbf8e9, 0xfcf9e9, 0xfdfaea, 0xfefbeb, 0xfffcec - } -}; - - - -uint32_t -svga_color_transform(uint32_t color) -{ - uint8_t *clr8 = (uint8_t *) &color; - if (!video_grayscale && !invert_display) - return color; - if (video_grayscale) { - if (video_graytype) { - if (video_graytype == 1) - color = ((54 * (uint32_t)clr8[2]) + (183 * (uint32_t)clr8[1]) + (18 * (uint32_t)clr8[0])) / 255; - else - color = ((uint32_t)clr8[2] + (uint32_t)clr8[1] + (uint32_t)clr8[0]) / 3; - } else - color = ((76 * (uint32_t)clr8[2]) + (150 * (uint32_t)clr8[1]) + (29 * (uint32_t)clr8[0])) / 255; - switch (video_grayscale) { - case 2: case 3: case 4: - color = shade[video_grayscale][color]; - break; - default: - clr8[3] = 0; - clr8[0] = color; - clr8[1] = clr8[2] = clr8[0]; - break; - } - } - if (invert_display) - color ^= 0x00ffffff; - return color; -} - - -void svga_render_blank(svga_t *svga) -{ - int x, xx; - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x < svga->hdisp; x++) - { - switch (svga->seqregs[1] & 9) - { - case 0: - for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 9) + xx + 32 + x_add] = svga_color_transform(0); - break; - case 1: - for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 8) + xx + 32 + x_add] = svga_color_transform(0); - break; - case 8: - for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 18) + xx + 32 + x_add] = svga_color_transform(0); - break; - case 9: - for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 16) + xx + 32 + x_add] = svga_color_transform(0); - break; - } - } -} - -void svga_render_text_40(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (svga->fullchange) - { - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add]; - int x, xx; - int drawcursor; - uint8_t chr, attr, dat; - uint32_t charaddr; - int fg, bg; - int xinc = (svga->seqregs[1] & 1) ? 16 : 18; - - for (x = 0; x < svga->hdisp; x += xinc) - { - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; - if (attr & 8) charaddr = svga->charsetb + (chr * 128); - else charaddr = svga->charseta + (chr * 128); - - if (drawcursor) - { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } - else - { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) - { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } - - fg = svga_color_transform(fg); - bg = svga_color_transform(bg); - - dat = svga->vram[charaddr + (svga->sc << 2)]; - if (svga->seqregs[1] & 1) - { - for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; - } - else - { - for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[16] = p[17] = bg; - else - p[16] = p[17] = (dat & 1) ? fg : bg; - } - svga->ma += 4; - p += xinc; - } - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_text_80(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (svga->fullchange) - { - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add]; - int x, xx; - int drawcursor; - uint8_t chr, attr, dat; - uint32_t charaddr; - int fg, bg; - int xinc = (svga->seqregs[1] & 1) ? 8 : 9; - - for (x = 0; x < svga->hdisp; x += xinc) - { - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; - - - if (attr & 8) charaddr = svga->charsetb + (chr * 128); - else charaddr = svga->charseta + (chr * 128); - - if (drawcursor) - { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } - else - { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) - { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } - - fg = svga_color_transform(fg); - bg = svga_color_transform(bg); - - dat = svga->vram[charaddr + (svga->sc << 2)]; - if (svga->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; - } - svga->ma += 4; - p += xinc; - } - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_text_80_ksc5601(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (svga->fullchange) - { - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add]; - int x, xx; - int drawcursor; - uint8_t chr, attr, dat, nextchr; - uint32_t charaddr; - int fg, bg; - int xinc = (svga->seqregs[1] & 1) ? 8 : 9; - - for (x = 0; x < svga->hdisp; x += xinc) - { - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; - - - if (drawcursor) - { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } - else - { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) - { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } - - fg = svga_color_transform(fg); - bg = svga_color_transform(bg); - - if(x + xinc < svga->hdisp && (chr & nextchr & 0x80)) - { - if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) - dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc]; - else - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc]; - } - else - { - if (attr & 8) charaddr = svga->charsetb + (chr * 128); - else charaddr = svga->charseta + (chr * 128); - - dat = svga->vram[charaddr + (svga->sc << 2)]; - } - if (svga->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; - } - svga->ma += 4; - p += xinc; - - if(x + xinc < svga->hdisp && (chr & nextchr & 0x80)) - { - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; - - if (drawcursor) - { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } - else - { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) - { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } - - if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) - dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc + 16]; - else - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16]; - if (svga->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; - } - - svga->ma += 4; - p += xinc; - x += xinc; - } - } - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_2bpp_lowres(svga_t *svga) -{ - int changed_offset; - - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) - { - int x; - int offset = ((8 - svga->scrollcache) << 1) + 16; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 16) - { - uint8_t dat[2]; - - dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]; - dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1]; - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - - p[0] = p[1] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]); - p[2] = p[3] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]); - p[4] = p[5] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]); - p[6] = p[7] = svga_color_transform(svga->pallook[svga->egapal[dat[0] & 3]]); - p[8] = p[9] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]); - p[10] = p[11] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]); - p[12] = p[13] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]); - p[14] = p[15] = svga_color_transform(svga->pallook[svga->egapal[dat[1] & 3]]); - - p += 16; - } - } -} - -void svga_render_2bpp_highres(svga_t *svga) -{ - int changed_offset; - - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) - { - int x; - int offset = (8 - svga->scrollcache) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 8) - { - uint8_t dat[2]; - - dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]; - dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1]; - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - - p[0] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]); - p[1] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]); - p[2] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]); - p[3] = svga_color_transform(svga->pallook[svga->egapal[dat[0] & 3]]); - p[4] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]); - p[5] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]); - p[6] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]); - p[7] = svga_color_transform(svga->pallook[svga->egapal[dat[1] & 3]]); - - p += 8; - } - } -} - -void svga_render_4bpp_lowres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = ((8 - svga->scrollcache) << 1) + 16; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 16) - { - uint8_t edat[4]; - uint8_t dat; - - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]); - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[2] = p[3] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[6] = p[7] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[10] = p[11] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[14] = p[15] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - - p += 16; - } - } -} - -void svga_render_4bpp_highres(svga_t *svga) -{ - int changed_offset; - - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) - { - int x; - int offset = (8 - svga->scrollcache) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 8) - { - uint8_t edat[4]; - uint8_t dat; - - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma | ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]); - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[1] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[3] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[5] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]); - p[7] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask]]); - - p += 8; - } - } -} - -void svga_render_8bpp_lowres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 8) - { - uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - - p[0] = p[1] = svga_color_transform(svga->pallook[dat & 0xff]); - p[2] = p[3] = svga_color_transform(svga->pallook[(dat >> 8) & 0xff]); - p[4] = p[5] = svga_color_transform(svga->pallook[(dat >> 16) & 0xff]); - p[6] = p[7] = svga_color_transform(svga->pallook[(dat >> 24) & 0xff]); - - svga->ma += 4; - p += 8; - } - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_8bpp_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 8) - { - uint32_t dat; - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = svga_color_transform(svga->pallook[dat & 0xff]); - p[1] = svga_color_transform(svga->pallook[(dat >> 8) & 0xff]); - p[2] = svga_color_transform(svga->pallook[(dat >> 16) & 0xff]); - p[3] = svga_color_transform(svga->pallook[(dat >> 24) & 0xff]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - p[4] = svga_color_transform(svga->pallook[dat & 0xff]); - p[5] = svga_color_transform(svga->pallook[(dat >> 8) & 0xff]); - p[6] = svga_color_transform(svga->pallook[(dat >> 16) & 0xff]); - p[7] = svga_color_transform(svga->pallook[(dat >> 24) & 0xff]); - - svga->ma += 8; - p += 8; - } - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_15bpp_lowres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 4) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - - p[x] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - - p[x] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_15bpp_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 8) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 3] = svga_color_transform(video_15to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 5] = svga_color_transform(video_15to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 7] = svga_color_transform(video_15to32[dat >> 16]); - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_16bpp_lowres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 4) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - - p[x] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - - p[x] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_16bpp_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 8) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 3] = svga_color_transform(video_16to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 5] = svga_color_transform(video_16to32[dat >> 16]); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 7] = svga_color_transform(video_16to32[dat >> 16]); - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_24bpp_lowres(svga_t *svga) -{ - int x, offset; - uint32_t fg; - - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - offset = (8 - (svga->scrollcache & 6)) + 24; - - for (x = 0; x <= svga->hdisp; x++) - { - fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - svga->ma += 3; - svga->ma &= svga->vram_display_mask; - ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = svga_color_transform(fg); - } - } -} - -void svga_render_24bpp_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 4) - { - uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[x] = svga_color_transform(dat & 0xffffff); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); - p[x + 1] = svga_color_transform(dat & 0xffffff); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); - p[x + 2] = svga_color_transform(dat & 0xffffff); - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); - p[x + 3] = svga_color_transform(dat & 0xffffff); - - svga->ma += 12; - } - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_32bpp_lowres(svga_t *svga) -{ - int x, offset; - uint32_t fg; - - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) - { - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - offset = (8 - (svga->scrollcache & 6)) + 24; - - for (x = 0; x <= svga->hdisp; x++) - { - fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = svga_color_transform(fg); - } - } -} - -/*72% - 91%*/ -void svga_render_32bpp_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x++) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = svga_color_transform(dat & 0xffffff); - } - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_ABGR8888_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x++) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = svga_color_transform((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); - } - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - } -} - -void svga_render_RGBA8888_highres(svga_t *svga) -{ - int y_add = enable_overscan ? (overscan_y >> 1) : 0; - int x_add = enable_overscan ? 8 : 0; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) - { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x++) - { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = svga_color_transform(dat >> 8); - } - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - } -} diff --git a/backup code/win/Makefile - Cópia.mingw b/backup code/win/Makefile - Cópia.mingw deleted file mode 100644 index 86a676bb2..000000000 --- a/backup code/win/Makefile - Cópia.mingw +++ /dev/null @@ -1,699 +0,0 @@ -# -# 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. -# -# Makefile for Win32 (MinGW32) environment. -# -# Version: @(#)Makefile.mingw 1.0.116 2018/05/01 -# -# Authors: Miran Grca, -# Fred N. van Kempen, -# - -# Various compile-time options. -ifndef STUFF -STUFF := -endif - -# Add feature selections here. -ifndef EXTRAS -EXTRAS := -endif - -ifndef DEV_BUILD -DEV_BUILD := n -endif - -ifeq ($(DEV_BUILD), y) - ifndef DEBUG - DEBUG := y - endif - ifndef DEV_BRANCH - DEV_BRANCH := y - endif - ifndef AMD_K - AMD_K := y - endif - ifndef CRASHDUMP - CRASHDUMP := y - endif - ifndef GREENB - GREENB := y - endif - ifndef I686 - I686 := y - endif - ifndef LASERXT - LASERXT := y - endif - ifndef MRTHOR - MRTHOR := y - endif - ifndef NV_RIVA - NV_RIVA := y - endif - ifndef PAS16 - PAS16 := y - endif - ifndef PORTABLE3 - PORTABLE3 := y - endif - ifndef STEALTH32 - STEALTH32 := y - endif - ifndef VNC - VNC := y - endif - ifndef XL24 - XL24 := y - endif -else - ifndef DEBUG - DEBUG := n - endif - ifndef DEV_BRANCH - DEV_BRANCH := n - endif - ifndef AMD_K - AMD_K := n - endif - ifndef CRASHDUMP - CRASHDUMP := n - endif - ifndef GREENB - GREENB := n - endif - ifndef I686 - I686 := n - endif - ifndef LASERXT - LASERXT := n - endif - ifndef MRTHOR - MRTHOR := n - endif - ifndef NV_RIVA - NV_RIVA := n - endif - ifndef PAS16 - PAS16 := n - endif - ifndef PORTABLE3 - PORTABLE3 := n - endif - ifndef STEALTH32 - STEALTH32 := n - endif - ifndef VGAWONDER - VGAWONDER := n - endif - ifndef VNC - VNC := n - endif - ifndef XL24 - XL24 := n - endif -endif - -# Defaults for several build options (possibly defined in a chained file.) -ifndef AUTODEP -AUTODEP := n -endif -ifndef OPTIM -OPTIM := n -endif -ifndef RELEASE -RELEASE := n -endif -ifndef X64 -X64 := n -endif -ifndef WX -WX := n -endif -ifndef USB -USB := n -endif -ifndef RDP -RDP := n -endif -ifndef OPENAL -OPENAL := y -endif -ifndef FLUIDSYNTH -FLUIDSYNTH := y -endif -ifndef MUNT -MUNT := y -endif -ifndef DYNAREC -DYNAREC := y -endif - - -# Name of the executable. -ifndef PROG - ifneq ($(WX), n) - PROG := Wx86Box - else - PROG := 86Box - endif -endif - -# WxWidgets basic info. Extract using the config program. -ifneq ($(WX), n) - EXPATH += wx - WX_CONFIG := wx-config.exe - ifeq ($(WX), y) - WX_PATH := C:/MinGW32/WxWidgets - WX_FLAGS := -I$(WX_PATH)/lib/wx/include/msw-unicode-3.0 \ - -I$(WX_PATH)/include/wx-3.0 \ - -D__WXMSW__ -DWX_PRECOMP -D_FILE_OFFSET_BITS=64 -pthread -# -lwx_mswu_gl-3.0 -lwxtiff-3.0 -llzma - WX_LIBS := -mwindows -mthreads -L$(WX_PATH)/lib \ - -lwx_mswu-3.0.dll \ - -lrpcrt4 -loleaut32 -lole32 -luuid \ - -lwinspool -lwinmm -lshell32 -lcomctl32 \ - -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32 - endif - ifeq ($(WX), static) - WX_PATH := C:/MinGW32/WxWidgets - WX_FLAGS := -I$(WX_PATH)/lib/wx/include/msw-unicode-3.0 \ - -I$(WX_PATH)/include/wx-3.0 \ - -D__WXMSW__ -DWX_PRECOMP -D_FILE_OFFSET_BITS=64 -pthread -# -lwx_mswu_gl-3.0 -lwxtiff-3.0 -llzma - WX_LIBS := -mwindows -mthreads -L$(WX_PATH)/lib \ - -lwx_mswu-3.0 -lwxscintilla-3.0 \ - -lwxjpeg-3.0 -lwxpng-3.0 -lwxzlib-3.0 \ - -lwxregexu-3.0 -lwxexpat-3.0 \ - -lrpcrt4 -loleaut32 -lole32 -luuid \ - -lwinspool -lwinmm -lshell32 -lcomctl32 \ - -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32 - endif -endif - - -######################################################################### -# Nothing should need changing from here on.. # -######################################################################### -VPATH := $(EXPATH) . cpu \ - cdrom disk floppy game machine \ - sound \ - sound/munt sound/munt/c_interface sound/munt/sha1 \ - sound/munt/srchelper \ - sound/resid-fp \ - scsi video network network/slirp win -ifeq ($(X64), y) -CPP := g++ -m64 -CC := gcc -m64 -else -CPP := g++ -m32 -CC := gcc -m32 -endif -WINDRES := windres -DEPS = -MMD -MF $*.d -c $< -DEPFILE := win/.depends - -# Set up the correct toolchain flags. -OPTS := $(EXTRAS) $(STUFF) -ifdef EXFLAGS -OPTS += $(EXFLAGS) -endif -ifdef EXINC -OPTS += -I$(EXINC) -endif -ifeq ($(X64), y) - ifeq ($(OPTIM), y) - DFLAGS := -march=native - else - DFLAGS := - endif -else - ifeq ($(OPTIM), y) - DFLAGS := -march=native - else - DFLAGS := -march=i686 - endif -endif -ifeq ($(DEBUG), y) - DFLAGS += -ggdb -DDEBUG - AOPTIM := - ifndef COPTIM - COPTIM := -Og - endif -else - DFLAGS += -g0 - ifeq ($(OPTIM), y) - AOPTIM := -mtune=native - ifndef COPTIM - COPTIM := -O3 -flto - endif - else - ifndef COPTIM - COPTIM := -O3 - endif - endif -endif -AFLAGS := -msse2 -mfpmath=sse -RFLAGS := --input-format=rc -O coff -ifeq ($(RELEASE), y) -OPTS += -DRELEASE_BUILD -RFLAGS += -DRELEASE_BUILD -endif -ifeq ($(VRAMDUMP), y) -OPTS += -DENABLE_VRAM_DUMP -RFLAGS += -DENABLE_VRAM_DUMP -endif -ifeq ($(X64), y) -PLATCG := codegen_x86-64.o -CGOPS := codegen_ops_x86-64.h -VCG := vid_voodoo_codegen_x86-64.h -else -PLATCG := codegen_x86.o -CGOPS := codegen_ops_x86.h -VCG := vid_voodoo_codegen_x86.h -endif - - -# Optional modules. -ifeq ($(DYNAREC), y) -OPTS += -DUSE_DYNAREC -RFLAGS += -DUSE_DYNAREC -DYNARECOBJ := 386_dynarec_ops.o \ - codegen.o \ - codegen_ops.o \ - codegen_timing_common.o codegen_timing_486.o \ - codegen_timing_686.o codegen_timing_pentium.o \ - codegen_timing_winchip.o $(PLATCG) -endif - -ifneq ($(WX), n) - OPTS += -DUSE_WX $(WX_FLAGS) - LIBS += $(WX_LIBS) - UIOBJ := wx_main.o wx_ui.o wx_stbar.o wx_render.o -else - UIOBJ := win_ui.o win_stbar.o \ - win_ddraw.o win_d3d.o \ - win_dialog.o win_about.o \ - win_settings.o win_devconf.o win_snd_gain.o \ - win_new_floppy.o win_jsconf.o -endif - -ifeq ($(OPENAL), y) -OPTS += -DUSE_OPENAL -endif -ifeq ($(FLUIDSYNTH), y) -OPTS += -DUSE_FLUIDSYNTH -FSYNTHOBJ := midi_fluidsynth.o -endif - -ifeq ($(MUNT), y) -OPTS += -DUSE_MUNT -MUNTOBJ := midi_mt32.o \ - Analog.o BReverbModel.o File.o FileStream.o LA32Ramp.o \ - LA32FloatWaveGenerator.o LA32WaveGenerator.o \ - MidiStreamParser.o Part.o Partial.o PartialManager.o \ - Poly.o ROMInfo.o SampleRateConverter_dummy.o Synth.o \ - Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o -endif - -ifeq ($(VNC), y) -OPTS += -DUSE_VNC -RFLAGS += -DUSE_VNC - ifneq ($(VNC_PATH), ) - OPTS += -I$(VNC_PATH)\INCLUDE - VNCLIB := -L$(VNC_PATH)\LIB - endif -VNCLIB += -lvncserver -VNCOBJ := vnc.o vnc_keymap.o -endif - -ifeq ($(RDP), y) -OPTS += -DUSE_RDP -RFLAGS += -DUSE_RDP - ifneq ($(RDP_PATH), ) - OPTS += -I$(RDP_PATH)\INCLUDE - RDPLIB := -L$(RDP_PATH)\LIB - endif -RDPLIB += -lrdp -RDPOBJ := rdp.o -endif - -# Options for the DEV branch. -ifeq ($(DEV_BRANCH), y) -OPTS += -DDEV_BRANCH -DEVBROBJ := - -ifeq ($(AMD_K), y) -OPTS += -DUSE_AMD_K -endif - -ifeq ($(CRASHDUMPOBJ), y) -OPTS += -DUSE_CRASHDUMP -DEVBROBJ += win_crashdump.o -endif - -ifeq ($(GREENB), y) -OPTS += -DUSE_GREENB -DEVBROBJ += m_at_4gpv31.o -endif - -ifeq ($(I686), y) -OPTS += -DUSE_I686 -DEVBROBJ += m_at_440fx.o -endif - -ifeq ($(LASERXT), y) -OPTS += -DUSE_LASERXT -DEVBROBJ += m_xt_laserxt.o -endif - -ifeq ($(MRTHOR), y) -OPTS += -DUSE_MRTHOR -endif - -ifeq ($(NV_RIVA), y) -OPTS += -DUSE_RIVA -DEVBROBJ += vid_nvidia.o -endif - -ifeq ($(PAS16), y) -OPTS += -DUSE_PAS16 -DEVBROBJ += snd_pas16.o -endif - -ifeq ($(PORTABLE3), y) -OPTS += -DUSE_PORTABLE3 -endif - -ifeq ($(STEALTH32), y) -OPTS += -DUSE_STEALTH32 -DEVBROBJ += vid_icd2061.o -endif - -ifeq ($(VGAWONDER), y) -OPTS += -DUSE_VGAWONDER -endif - -ifeq ($(XL24), y) -OPTS += -DUSE_XL24 -endif - -endif - - -# Options for works-in-progress. -ifndef SERIAL -SERIAL := serial.o -endif - - -# Final versions of the toolchain flags. -CFLAGS := $(WX_FLAGS) $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ - $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ - -fno-strict-aliasing -CFLAGS := $(CFLAGS) - - -######################################################################### -# Create the (final) list of objects to build. # -######################################################################### -MAINOBJ := pc.o config.o random.o timer.o io.o dma.o nmi.o pic.o \ - pit.o ppi.o pci.o mca.o mcr.o mem.o memregs.o rom.o \ - device.o nvr.o nvr_at.o nvr_ps2.o $(VNCOBJ) $(RDPOBJ) - -INTELOBJ := intel.o \ - intel_flash.o \ - intel_sio.o intel_piix.o - -CPUOBJ := cpu.o cpu_table.o \ - 808x.o 386.o 386_dynarec.o \ - x86seg.o x87.o \ - $(DYNARECOBJ) - -MCHOBJ := machine.o machine_table.o \ - m_xt.o m_xt_compaq.o \ - m_xt_t1000.o m_xt_t1000_vid.o \ - m_xt_xi8088.o \ - m_pcjr.o \ - m_amstrad.o \ - m_europc.o \ - m_olivetti_m24.o m_tandy.o \ - m_at.o \ - m_at_ali1429.o m_at_commodore.o \ - m_at_neat.o m_at_headland.o \ - m_at_t3100e.o m_at_t3100e_vid.o \ - m_ps1.o m_ps1_hdc.o \ - m_ps2_isa.o m_ps2_mca.o \ - m_at_opti495.o m_at_scat.o \ - m_at_compaq.o m_at_wd76c10.o \ - m_at_sis_85c471.o m_at_sis_85c496.o \ - m_at_430lx_nx.o m_at_430fx.o \ - m_at_430hx.o m_at_430vx.o - -DEVOBJ := bugger.o lpt.o $(SERIAL) \ - sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o \ - sio_pc87306.o sio_w83877f.o sio_um8669f.o \ - keyboard.o \ - keyboard_xt.o keyboard_at.o \ - gameport.o \ - joystick_standard.o joystick_ch_flightstick_pro.o \ - joystick_sw_pad.o joystick_tm_fcs.o \ - mouse.o \ - mouse_bus.o \ - mouse_serial.o mouse_ps2.o - -FDDOBJ := fdd.o fdc.o fdi2raw.o \ - fdd_common.o fdd_86f.o \ - fdd_fdi.o fdd_imd.o fdd_img.o fdd_json.o \ - fdd_td0.o - -HDDOBJ := hdd.o \ - hdd_image.o hdd_table.o \ - hdc.o \ - hdc_mfm_xt.o hdc_mfm_at.o \ - hdc_xta.o \ - hdc_esdi_at.o hdc_esdi_mca.o \ - hdc_xtide.o hdc_ide.o - -CDROMOBJ := cdrom.o \ - cdrom_dosbox.o cdrom_image.o cdrom_null.o - -ZIPOBJ := zip.o - -ifeq ($(USB), y) -USBOBJ := usb.o -endif - -SCSIOBJ := scsi.o \ - scsi_bus.o scsi_device.o \ - scsi_disk.o \ - scsi_x54x.o \ - scsi_aha154x.o scsi_buslogic.o \ - scsi_ncr5380.o scsi_ncr53c810.o - -NETOBJ := network.o \ - net_pcap.o \ - net_slirp.o \ - bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \ - ip_input.o queue.o tcp_input.o debug.o ip_output.o \ - sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o \ - net_ne2000.o - -SNDOBJ := sound.o \ - openal.o \ - snd_opl.o snd_dbopl.o \ - dbopl.o nukedopl.o \ - snd_resid.o \ - convolve.o convolve-sse.o envelope.o extfilt.o \ - filter.o pot.o sid.o voice.o wave6581__ST.o \ - wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ - wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ - wave8580_PST.o wave.o \ - midi.o midi_system.o \ - snd_speaker.o \ - snd_pssj.o \ - snd_lpt_dac.o snd_lpt_dss.o \ - snd_adlib.o snd_adlibgold.o snd_ad1848.o snd_audiopci.o \ - snd_cms.o \ - snd_gus.o \ - snd_sb.o snd_sb_dsp.o \ - snd_emu8k.o snd_mpu401.o \ - snd_sn76489.o snd_ssi2001.o \ - snd_wss.o \ - snd_ym7128.o - -VIDOBJ := video.o \ - vid_table.o \ - vid_cga.o vid_cga_comp.o \ - vid_compaq_cga.o \ - vid_mda.o \ - vid_hercules.o vid_herculesplus.o vid_incolor.o \ - vid_colorplus.o \ - vid_genius.o \ - vid_wy700.o \ - vid_ega.o vid_ega_render.o \ - vid_svga.o vid_svga_render.o \ - vid_vga.o \ - vid_ati_eeprom.o \ - vid_ati18800.o vid_ati28800.o \ - vid_ati_mach64.o vid_ati68860_ramdac.o \ - vid_ics2595.o \ - vid_cl54xx.o \ - vid_et4000.o vid_sc1502x_ramdac.o \ - vid_et4000w32.o vid_stg_ramdac.o \ - vid_oak_oti.o \ - vid_paradise.o \ - vid_ti_cf62011.o \ - vid_tvga.o \ - vid_tgui9440.o vid_tkd8001_ramdac.o \ - vid_s3.o vid_s3_virge.o \ - vid_sdac_ramdac.o \ - vid_voodoo.o - -PLATOBJ := win.o \ - win_dynld.o win_thread.o \ - win_cdrom.o win_keyboard.o \ - win_mouse.o win_joystick.o win_midi.o - -OBJ := $(MAINOBJ) $(INTELOBJ) $(CPUOBJ) $(MCHOBJ) $(DEVOBJ) \ - $(FDDOBJ) $(CDROMOBJ) $(ZIPOBJ) $(HDDOBJ) \ - $(USBOBJ) $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) \ - $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) \ - $(DEVBROBJ) -ifdef EXOBJ -OBJ += $(EXOBJ) -endif - -LIBS := -mwindows \ - -lopenal.dll \ - -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 \ - -lcomctl32 -lwinmm -ifeq ($(VNC), y) -LIBS += $(VNCLIB) -lws2_32 -endif -ifeq ($(RDP), y) -LIBS += $(RDPLIB) -endif -ifneq ($(WX), n) -LIBS += $(WX_LIBS) -lm -endif -LIBS += -lpng -lz -lwsock32 -liphlpapi -LIBS += -static -lstdc++ -lgcc -ifneq ($(X64), y) -LIBS += -Wl,--large-address-aware -endif - - -# Build module rules. -ifeq ($(AUTODEP), y) -%.o: %.c - @echo $< - @$(CC) $(CFLAGS) $(DEPS) -c $< - -%.o: %.cc - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -c $< - -%.o: %.cpp - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -c $< -else -%.o: %.c - @echo $< - @$(CC) $(CFLAGS) -c $< - -%.o: %.cc - @echo $< - @$(CPP) $(CXXFLAGS) -c $< - -%.o: %.cpp - @echo $< - @$(CPP) $(CXXFLAGS) -c $< - -%.d: %.c $(wildcard $*.d) - @echo $< - @$(CC) $(CFLAGS) $(DEPS) -E $< >NUL - -%.d: %.cc $(wildcard $*.d) - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -E $< >NUL - -%.d: %.cpp $(wildcard $*.d) - @echo $< - @$(CPP) $(CXXFLAGS) $(DEPS) -E $< >NUL -endif - - -all: $(PROG).exe pcap_if.exe - - -86Box.res: 86Box.rc - @echo Processing $< - @$(WINDRES) $(RFLAGS) $(EXTRAS) -i $< -o 86Box.res - -$(PROG).exe: $(OBJ) 86Box.res - @echo Linking $(PROG).exe .. - @$(CC) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) -ifneq ($(DEBUG), y) - @strip $(PROG).exe -endif - -pcap_if.res: pcap_if.rc - @echo Processing $< - @$(WINDRES) $(RFLAGS) -i $< -o pcap_if.res - -pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res - @echo Linking pcap_if.exe .. - @$(CC) -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res -ifneq ($(DEBUG), y) - @strip pcap_if.exe -endif - -hello.exe: hello.o - $(CXX) $(LDFLAGS) -o hello.exe hello.o $(WXLIBS) $(LIBS) -ifneq ($(DEBUG), y) - @strip hello.exe -endif - - -clean: - @echo Cleaning objects.. - @-rm -f *.o 2>NUL - @-rm -f *.res 2>NUL - -clobber: clean - @echo Cleaning executables.. - @-rm -f *.d 2>NUL - @-rm -f *.exe 2>NUL -# @-rm -f $(DEPFILE) 2>NUL - -ifneq ($(AUTODEP), y) -depclean: - @-rm -f $(DEPFILE) 2>NUL - @echo Creating dependencies.. - @echo # Run "make depends" to re-create this file. >$(DEPFILE) - -depends: DEPOBJ=$(OBJ:%.o=%.d) -depends: depclean $(OBJ:%.o=%.d) - @-cat $(DEPOBJ) >>$(DEPFILE) - @-rm -f $(DEPOBJ) - -$(DEPFILE): -endif - - -# Module dependencies. -ifeq ($(AUTODEP), y) -#-include $(OBJ:%.o=%.d) (better, but sloooowwwww) --include *.d -else -include $(wildcard $(DEPFILE)) -endif - - -# End of Makefile.mingw. diff --git a/backup code/win/win_cdrom - Cópia.c b/backup code/win/win_cdrom - Cópia.c deleted file mode 100644 index 666ac7ccf..000000000 --- a/backup code/win/win_cdrom - Cópia.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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. - * - * Handle the platform-side of CDROM drives. - * - * Version: @(#)win_cdrom.c 1.0.7 2018/03/26 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include "../config.h" -#include "../disk/hdd.h" -#include "../disk/zip.h" -#include "../scsi/scsi.h" -#include "../cdrom/cdrom.h" -#include "../cdrom/cdrom_image.h" -#include "../cdrom/cdrom_null.h" -#include "../scsi/scsi_disk.h" -#include "../plat.h" -#include "../ui.h" -#include "win.h" - - -void -cdrom_eject(uint8_t id) -{ - if (cdrom_drives[id].host_drive == 0) { - /* Switch from empty to empty. Do nothing. */ - return; - } - - if (cdrom_image[id].prev_image_path) { - free(cdrom_image[id].prev_image_path); - cdrom_image[id].prev_image_path = NULL; - } - - if (cdrom_drives[id].host_drive == 200) { - cdrom_image[id].prev_image_path = (wchar_t *) malloc(1024); - wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path); - } - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - cdrom[id]->handler->exit(id); - cdrom_close_handler(id); - memset(cdrom_image[id].image_path, 0, 2048); - cdrom_null_open(id); - if (cdrom_drives[id].bus_type) { - /* Signal disc change to the emulated machine. */ - cdrom_insert(cdrom[id]); - } - - ui_sb_check_menu_item(SB_CDROM|id, IDM_CDROM_IMAGE | id, MF_UNCHECKED); - cdrom_drives[id].host_drive=0; - ui_sb_check_menu_item(SB_CDROM|id, IDM_CDROM_EMPTY | id, MF_CHECKED); - ui_sb_update_icon_state(SB_CDROM|id, 1); - ui_sb_enable_menu_item(SB_CDROM|id, IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); - ui_sb_update_tip(SB_CDROM|id); - - config_save(); -} - - -void -cdrom_reload(uint8_t id) -{ - if ((cdrom_drives[id].host_drive == cdrom_drives[id].prev_host_drive) || (cdrom_drives[id].prev_host_drive == 0) || (cdrom_drives[id].host_drive != 0)) { - /* Switch from empty to empty. Do nothing. */ - return; - } - - cdrom_close_handler(id); - memset(cdrom_image[id].image_path, 0, 2048); - - if (cdrom_drives[id].prev_host_drive == 200) { - wcscpy(cdrom_image[id].image_path, cdrom_image[id].prev_image_path); - free(cdrom_image[id].prev_image_path); - cdrom_image[id].prev_image_path = NULL; - image_open(id, cdrom_image[id].image_path); - if (cdrom_drives[id].bus_type) { - /* Signal disc change to the emulated machine. */ - cdrom_insert(cdrom[id]); - } - if (wcslen(cdrom_image[id].image_path) == 0) { - ui_sb_check_menu_item(SB_CDROM|id, IDM_CDROM_EMPTY | id, MF_CHECKED); - cdrom_drives[id].host_drive = 0; - ui_sb_check_menu_item(SB_CDROM|id, IDM_CDROM_IMAGE | id, MF_UNCHECKED); - ui_sb_update_icon_state(SB_CDROM|id, 1); - } else { - ui_sb_check_menu_item(SB_CDROM|id, IDM_CDROM_EMPTY | id, MF_UNCHECKED); - cdrom_drives[id].host_drive = 200; - ui_sb_check_menu_item(SB_CDROM|id, IDM_CDROM_IMAGE | id, MF_CHECKED); - ui_sb_update_icon_state(SB_CDROM|id, 0); - } - } - - ui_sb_enable_menu_item(SB_CDROM|id, IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - ui_sb_update_tip(SB_CDROM|id); - - config_save(); -} - - -void -zip_eject(uint8_t id) -{ - zip_close(id); - if (zip_drives[id].bus_type) { - /* Signal disk change to the emulated machine. */ - zip_insert(id); - } - - ui_sb_update_icon_state(SB_ZIP | id, 1); - ui_sb_enable_menu_item(SB_ZIP|id, IDM_ZIP_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - ui_sb_enable_menu_item(SB_ZIP|id, IDM_ZIP_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); - ui_sb_update_tip(SB_ZIP | id); - config_save(); -} - - -void -zip_reload(uint8_t id) -{ - zip_disk_reload(id); - if (wcslen(zip_drives[id].image_path) == 0) { - ui_sb_enable_menu_item(SB_ZIP|id, IDM_ZIP_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - ui_sb_update_icon_state(SB_ZIP|id, 1); - } else { - ui_sb_enable_menu_item(SB_ZIP|id, IDM_ZIP_EJECT | id, MF_BYCOMMAND | MF_ENABLED); - ui_sb_update_icon_state(SB_ZIP|id, 0); - } - - ui_sb_enable_menu_item(SB_ZIP|id, IDM_ZIP_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - ui_sb_update_tip(SB_ZIP|id); - - config_save(); -} diff --git a/backup code/win/win_new_floppy - Cópia.c b/backup code/win/win_new_floppy - Cópia.c deleted file mode 100644 index cc62c77b7..000000000 --- a/backup code/win/win_new_floppy - Cópia.c +++ /dev/null @@ -1,711 +0,0 @@ -/* - * 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. - * - * Handle the New Floppy Image dialog. - * - * Version: @(#)win_new_floppy.c 1.0.8 2018/05/25 - * - * Authors: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../plat.h" -#include "../random.h" -#include "../ui.h" -#include "../disk/zip.h" -#include "win.h" - - -typedef struct { - int hole; - int sides; - int data_rate; - int encoding; - int rpm; - int tracks; - int sectors; /* For IMG and Japanese FDI only. */ - int sector_len; /* For IMG and Japanese FDI only. */ - int media_desc; - int spc; - int num_fats; - int spfat; - int root_dir_entries; -} disk_size_t; - - -static const disk_size_t disk_sizes[14] = { { 0, 1, 2, 1, 0, 40, 8, 2, 0xfe, 2, 2, 1, 112 }, /* 160k */ - { 0, 1, 2, 1, 0, 40, 9, 2, 0xfc, 2, 2, 1, 112 }, /* 180k */ - { 0, 2, 2, 1, 0, 40, 8, 2, 0xff, 2, 2, 1, 112 }, /* 320k */ - { 0, 2, 2, 1, 0, 40, 9, 2, 0xfd, 2, 2, 2, 112 }, /* 360k */ - { 0, 2, 2, 1, 0, 80, 8, 2, 0xfb, 2, 2, 2, 112 }, /* 640k */ - { 0, 2, 2, 1, 0, 80, 9, 2, 0xf9, 2, 2, 3, 112 }, /* 720k */ - { 1, 2, 0, 1, 1, 80, 15, 2, 0xf9, 1, 2, 7, 224 }, /* 1.2M */ - { 1, 2, 0, 1, 1, 77, 8, 3, 0xfe, 1, 2, 2, 192 }, /* 1.25M */ - { 1, 2, 0, 1, 0, 80, 18, 2, 0xf0, 1, 2, 9, 224 }, /* 1.44M */ - { 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 2, 2, 5, 16 }, /* DMF cluster 1024 */ - { 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 4, 2, 3, 16 }, /* DMF cluster 2048 */ - { 2, 2, 3, 1, 0, 80, 36, 2, 0xf0, 2, 2, 9, 240 }, /* 2.88M */ - { 0, 64, 0, 0, 0, 96, 32, 2, 0, 0, 0, 0, 0 }, /* ZIP 100 */ - { 0, 64, 0, 0, 0, 239, 32, 2, 0, 0, 0, 0, 0 } }; /* ZIP 250 */ - -static unsigned char *empty; - - -static int -create_86f(WCHAR *file_name, disk_size_t disk_size, uint8_t rpm_mode) -{ - FILE *f; - - uint32_t magic = 0x46423638; - uint16_t version = 0x020B; - uint16_t dflags = 0; - uint16_t tflags = 0; - uint32_t index_hole_pos = 0; - uint32_t tarray[512]; - uint32_t array_size, array_size2; - uint32_t track_base, track_size; - int i; - uint32_t shift = 0; - - dflags = 0; /* Has surface data? - Assume no for now. */ - dflags |= (disk_size.hole << 1); /* Hole */ - dflags |= ((disk_size.sides - 1) << 3); /* Sides. */ - dflags |= (0 << 4); /* Write protect? - Assume no for now. */ - dflags |= (rpm_mode << 5); /* RPM mode. */ - dflags |= (0 << 7); /* Has extra bit cells? - Assume no for now. */ - - tflags = disk_size.data_rate; /* Data rate. */ - tflags |= (disk_size.encoding << 3); /* Encoding. */ - tflags |= (disk_size.rpm << 5); /* RPM. */ - - switch (disk_size.hole) { - case 0: - case 1: - default: - switch(rpm_mode) { - case 1: - array_size = 25250; - break; - case 2: - array_size = 25374; - break; - case 3: - array_size = 25750; - break; - default: - array_size = 25000; - break; - } - break; - case 2: - switch(rpm_mode) { - case 1: - array_size = 50500; - break; - case 2: - array_size = 50750; - break; - case 3: - array_size = 51000; - break; - default: - array_size = 50000; - break; - } - break; - } - - array_size2 = (array_size << 3); - array_size = (array_size2 >> 4) << 1; - if (array_size2 & 15) - array_size += 2; - - empty = (unsigned char *) malloc(array_size); - - memset(tarray, 0, 2048); - memset(empty, 0, array_size); - - f = plat_fopen(file_name, L"wb"); - if (!f) - return 0; - - fwrite(&magic, 4, 1, f); - fwrite(&version, 2, 1, f); - fwrite(&dflags, 2, 1, f); - - track_size = array_size + 6; - - track_base = 8 + ((disk_size.sides == 2) ? 2048 : 1024); - - if (disk_size.tracks <= 43) - shift = 1; - - for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) - tarray[i] = track_base + (i * track_size); - - fwrite(tarray, 1, (disk_size.sides == 2) ? 2048 : 1024, f); - - for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) { - fwrite(&tflags, 2, 1, f); - fwrite(&index_hole_pos, 4, 1, f); - fwrite(empty, 1, array_size, f); - } - - free(empty); - - fclose(f); - - return 1; -} - - -static int is_zip; - - -static int -create_sector_image(WCHAR *file_name, disk_size_t disk_size, uint8_t is_fdi) -{ - FILE *f; - uint32_t total_size = 0; - uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; - uint32_t root_dir_bytes = 0; - uint32_t fat_size = 0; - uint32_t fat1_offs = 0; - uint32_t fat2_offs = 0; - uint32_t zero_bytes = 0; - uint16_t base = 0x1000; - - f = plat_fopen(file_name, L"wb"); - if (!f) - return 0; - - sector_bytes = (128 << disk_size.sector_len); - total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors; - if (total_sectors > ZIP_SECTORS) - total_sectors = ZIP_250_SECTORS; - total_size = total_sectors * sector_bytes; - root_dir_bytes = (disk_size.root_dir_entries << 5); - fat_size = (disk_size.spfat * sector_bytes); - fat1_offs = sector_bytes; - fat2_offs = fat1_offs + fat_size; - zero_bytes = fat2_offs + fat_size + root_dir_bytes; - - if (!is_zip && is_fdi) { - empty = (unsigned char *) malloc(base); - memset(empty, 0, base); - - *(uint32_t *) &(empty[0x08]) = (uint32_t) base; - *(uint32_t *) &(empty[0x0C]) = total_size; - *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; - - fwrite(empty, 1, base, f); - free(empty); - } - - empty = (unsigned char *) malloc(total_size); - memset(empty, 0x00, zero_bytes); - - if (!is_zip) { - memset(empty + zero_bytes, 0xF6, total_size - zero_bytes); - - empty[0x00] = 0xEB; /* Jump to make MS-DOS happy. */ - empty[0x01] = 0x58; - empty[0x02] = 0x90; - - empty[0x03] = 0x38; /* '86BOX5.0' OEM ID. */ - empty[0x04] = 0x36; - empty[0x05] = 0x42; - empty[0x06] = 0x4F; - empty[0x07] = 0x58; - empty[0x08] = 0x35; - empty[0x09] = 0x2E; - empty[0x0A] = 0x30; - - *(uint16_t *) &(empty[0x0B]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x0D]) = (uint8_t) disk_size.spc; - *(uint16_t *) &(empty[0x0E]) = (uint16_t) 1; - *(uint8_t *) &(empty[0x10]) = (uint8_t) disk_size.num_fats; - *(uint16_t *) &(empty[0x11]) = (uint16_t) disk_size.root_dir_entries; - *(uint16_t *) &(empty[0x13]) = (uint16_t) total_sectors; - *(uint8_t *) &(empty[0x15]) = (uint8_t) disk_size.media_desc; - *(uint16_t *) &(empty[0x16]) = (uint16_t) disk_size.spfat; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x1A]) = (uint8_t) disk_size.sides; - - empty[0x26] = 0x29; /* ')' followed by randomly-generated volume serial number. */ - empty[0x27] = random_generate(); - empty[0x28] = random_generate(); - empty[0x29] = random_generate(); - empty[0x2A] = random_generate(); - - memset(&(empty[0x2B]), 0x20, 11); - - empty[0x36] = 'F'; - empty[0x37] = 'A'; - empty[0x38] = 'T'; - empty[0x39] = '1'; - empty[0x3A] = '2'; - empty[0x3B] = ' '; - empty[0x3C] = ' '; - empty[0x3D] = ' '; - - empty[0x1FE] = 0x55; - empty[0x1FF] = 0xAA; - - empty[fat1_offs + 0x00] = empty[fat2_offs + 0x00] = empty[0x15]; - empty[fat1_offs + 0x01] = empty[fat2_offs + 0x01] = 0xFF; - empty[fat1_offs + 0x02] = empty[fat2_offs + 0x02] = 0xFF; - } - - fwrite(empty, 1, total_size, f); - free(empty); - - fclose(f); - - return 1; -} - - -static int -create_zip_sector_image(WCHAR *file_name, disk_size_t disk_size, uint8_t is_zdi, HWND hwnd) -{ - HWND h; - FILE *f; - uint32_t total_size = 0; - uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; - uint32_t root_dir_bytes = 0; - uint32_t fat_size = 0; - uint32_t fat1_offs = 0; - uint32_t fat2_offs = 0; - uint32_t zero_bytes = 0; - uint16_t base = 0x1000; - uint32_t pbar_max = 0; - uint32_t i; - - f = plat_fopen(file_name, L"wb"); - if (!f) - return 0; - - sector_bytes = (128 << disk_size.sector_len); - total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors; - if (total_sectors > ZIP_SECTORS) - total_sectors = ZIP_250_SECTORS; - total_size = total_sectors * sector_bytes; - root_dir_bytes = (disk_size.root_dir_entries << 5); - fat_size = (disk_size.spfat * sector_bytes); - fat1_offs = sector_bytes; - fat2_offs = fat1_offs + fat_size; - zero_bytes = fat2_offs + fat_size + root_dir_bytes; - - pbar_max = total_size; - if (is_zdi) - pbar_max += base; - pbar_max >>= 11; - pbar_max--; - - h = GetDlgItem(hwnd, IDC_COMBO_RPM_MODE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hwnd, IDT_1751); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hwnd, IDC_PBAR_IMG_CREATE); - SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) pbar_max); - SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - h = GetDlgItem(hwnd, IDT_1757); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - - h = GetDlgItem(hwnd, IDC_PBAR_IMG_CREATE); - pbar_max++; - - if (is_zdi) { - empty = (unsigned char *) malloc(base); - memset(empty, 0, base); - - *(uint32_t *) &(empty[0x08]) = (uint32_t) base; - *(uint32_t *) &(empty[0x0C]) = total_size; - *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; - - fwrite(empty, 1, 2048, f); - SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); - - fwrite(&empty[0x0800], 1, 2048, f); - free(empty); - - SendMessage(h, PBM_SETPOS, (WPARAM) 2, (LPARAM) 0); - pbar_max -= 2; - } - - empty = (unsigned char *) malloc(total_size); - memset(empty, 0x00, zero_bytes); - - if (total_sectors == ZIP_SECTORS) { - /* ZIP 100 */ - /* MBR */ - *(uint64_t *) &(empty[0x0000]) = 0x0000030000025245LL; - *(uint64_t *) &(empty[0x0008]) = 0x0000000000000000LL; - *(uint64_t *) &(empty[0x0010]) = 0x0900E90300000100LL; - *(uint64_t *) &(empty[0x0018]) = 0x726F70726F430100LL; - *(uint64_t *) &(empty[0x0020]) = 0x202D206E6F697461LL; - *(uint64_t *) &(empty[0x0028]) = 0x30392F33322F3131LL; - - *(uint64_t *) &(empty[0x01AE]) = 0x0116010100E905E2LL; - *(uint64_t *) &(empty[0x01B6]) = 0x226BEDCE014E0135LL; - *(uint64_t *) &(empty[0x01BE]) = 0x5E203F0600010180LL; - *(uint64_t *) &(empty[0x01C6]) = 0x0002FE6000000020LL; - - *(uint16_t *) &(empty[0x01FE]) = 0xAA55; - - /* 4 sectors filled with 0xFA */ - memset(&(empty[0x0200]), 0xFA, 0x0800); - - /* Iomega_Reserved sector */ - *(uint64_t *) &(empty[0x0A00]) = 0x0500000000004D50LL; - *(uint64_t *) &(empty[0x0A08]) = 0xAFF9010051060100LL; - - *(uint64_t *) &(empty[0x0A30]) = 0x525F6167656D6F49LL; - *(uint64_t *) &(empty[0x0A38]) = 0x0064657672657365LL; - - *(uint64_t *) &(empty[0x0A54]) = 0x03000000AFF90100LL; - - /* 26 sectors filled with 0x48 */ - memset(&(empty[0x0C00]), 0x48, 0x3400); - - /* Boot sector */ - *(uint64_t *) &(empty[0x4000]) = 0x584F4236389058EBLL; - *(uint64_t *) &(empty[0x4008]) = 0x0001040200302E35LL; - *(uint64_t *) &(empty[0x4010]) = 0x00C0F80000020002LL; - *(uint64_t *) &(empty[0x4018]) = 0x0000002000400020LL; - *(uint32_t *) &(empty[0x4020]) = 0x0002FFE0; - *(uint16_t *) &(empty[0x4024]) = 0x0080; - - empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ - empty[0x4027] = random_generate(); - empty[0x4028] = random_generate(); - empty[0x4029] = random_generate(); - empty[0x402A] = random_generate(); - - memset(&(empty[0x402B]), 0x00, 0x000B); - memset(&(empty[0x4036]), 0x20, 0x0008); - - empty[0x4036] = 'F'; - empty[0x4037] = 'A'; - empty[0x4038] = 'T'; - empty[0x4039] = '1'; - empty[0x403A] = '6'; - - empty[0x41FE] = 0x55; - empty[0x41FF] = 0xAA; - - empty[0x4200] = empty[0x1C200] = empty[0x4015]; - empty[0x4201] = empty[0x1C201] = 0xFF; - empty[0x4202] = empty[0x1C202] = 0xFF; - empty[0x4203] = empty[0x1C203] = 0xFF; - - /* Root directory = 0x34200 - Data = 0x38200 */ - } else { - /* ZIP 250 */ - /* MBR */ - *(uint64_t *) &(empty[0x0000]) = 0x2054524150492EEBLL; - *(uint64_t *) &(empty[0x0008]) = 0x3930302065646F63LL; - *(uint64_t *) &(empty[0x0010]) = 0x67656D6F49202D20LL; - *(uint64_t *) &(empty[0x0018]) = 0x726F70726F432061LL; - *(uint64_t *) &(empty[0x0020]) = 0x202D206E6F697461LL; - *(uint64_t *) &(empty[0x0028]) = 0x30392F33322F3131LL; - - *(uint64_t *) &(empty[0x01AE]) = 0x0116010100E900E9LL; - *(uint64_t *) &(empty[0x01B6]) = 0x2E32A7AC014E0135LL; - - *(uint64_t *) &(empty[0x01EE]) = 0xEE203F0600010180LL; - *(uint64_t *) &(empty[0x01F6]) = 0x000777E000000020LL; - *(uint16_t *) &(empty[0x01FE]) = 0xAA55; - - /* 31 sectors filled with 0x48 */ - memset(&(empty[0x0200]), 0x48, 0x3E00); - - /* The second sector begins with some strange data - in my reference image. */ - *(uint64_t *) &(empty[0x0200]) = 0x3831393230334409LL; - *(uint64_t *) &(empty[0x0208]) = 0x6A57766964483130LL; - *(uint64_t *) &(empty[0x0210]) = 0x3C3A34676063653FLL; - *(uint64_t *) &(empty[0x0218]) = 0x586A56A8502C4161LL; - *(uint64_t *) &(empty[0x0220]) = 0x6F2D702535673D6CLL; - *(uint64_t *) &(empty[0x0228]) = 0x255421B8602D3456LL; - *(uint64_t *) &(empty[0x0230]) = 0x577B22447B52603ELL; - *(uint64_t *) &(empty[0x0238]) = 0x46412CC871396170LL; - *(uint64_t *) &(empty[0x0240]) = 0x704F55237C5E2626LL; - *(uint64_t *) &(empty[0x0248]) = 0x6C7932C87D5C3C20LL; - *(uint64_t *) &(empty[0x0250]) = 0x2C50503E47543D6ELL; - *(uint64_t *) &(empty[0x0258]) = 0x46394E807721536ALL; - *(uint64_t *) &(empty[0x0260]) = 0x505823223F245325LL; - *(uint64_t *) &(empty[0x0268]) = 0x365C79B0393B5B6ELL; - - /* Boot sector */ - *(uint64_t *) &(empty[0x4000]) = 0x584F4236389058EBLL; - *(uint64_t *) &(empty[0x4008]) = 0x0001080200302E35LL; - *(uint64_t *) &(empty[0x4010]) = 0x00EFF80000020002LL; - *(uint64_t *) &(empty[0x4018]) = 0x0000002000400020LL; - *(uint32_t *) &(empty[0x4020]) = 0x000777E0; - *(uint16_t *) &(empty[0x4024]) = 0x0080; - - empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ - empty[0x4027] = random_generate(); - empty[0x4028] = random_generate(); - empty[0x4029] = random_generate(); - empty[0x402A] = random_generate(); - - memset(&(empty[0x402B]), 0x00, 0x000B); - memset(&(empty[0x4036]), 0x20, 0x0008); - - empty[0x4036] = 'F'; - empty[0x4037] = 'A'; - empty[0x4038] = 'T'; - empty[0x4039] = '1'; - empty[0x403A] = '6'; - - empty[0x41FE] = 0x55; - empty[0x41FF] = 0xAA; - - empty[0x4200] = empty[0x22000] = empty[0x4015]; - empty[0x4201] = empty[0x22001] = 0xFF; - empty[0x4202] = empty[0x22002] = 0xFF; - empty[0x4203] = empty[0x22003] = 0xFF; - - /* Root directory = 0x3FE00 - Data = 0x38200 */ - } - - for (i = 0; i < pbar_max; i++) { - fwrite(&empty[i << 11], 1, 2048, f); - SendMessage(h, PBM_SETPOS, (WPARAM) i + 2, (LPARAM) 0); - } - - free(empty); - - fclose(f); - - return 1; -} - - -static int fdd_id, sb_part; - -static int file_type = 0; /* 0 = IMG, 1 = Japanese FDI, 2 = 86F */ -static wchar_t fd_file_name[512]; - - -/* Show a MessageBox dialog. This is nasty, I know. --FvK */ -static int -new_floppy_msgbox(HWND hwnd, int type, void *arg) -{ - HWND h; - int i; - - h = hwndMain; - hwndMain = hwnd; - - i = ui_msgbox(type, arg); - - hwndMain = h; - - return(i); -} - - -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int i = 0; - int wcs_len, ext_offs; - wchar_t *ext; - uint8_t disk_size, rpm_mode; - int ret; - FILE *f; - int zip_types; - wchar_t *twcs; - - switch (message) { - case WM_INITDIALOG: - plat_pause(1); - memset(fd_file_name, 0, 512 * sizeof(wchar_t)); - h = GetDlgItem(hdlg, IDC_COMBO_DISK_SIZE); - if (is_zip) { - zip_types = zip_drives[fdd_id].is_250 ? 2 : 1; - for (i = 0; i < zip_types; i++) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_5900 + i)); - } else { - for (i = 0; i < 12; i++) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_5888 + i)); - } - SendMessage(h, CB_SETCURSEL, 0, 0); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_COMBO_RPM_MODE); - for (i = 0; i < 4; i++) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_6144 + i)); - SendMessage(h, CB_SETCURSEL, 0, 0); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, IDT_1751); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, IDOK); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, IDT_1757); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - h = GetDlgItem(hdlg, IDC_COMBO_DISK_SIZE); - disk_size = SendMessage(h, CB_GETCURSEL, 0, 0); - if (is_zip) - disk_size += 12; - if (file_type == 2) { - h = GetDlgItem(hdlg, IDC_COMBO_RPM_MODE); - rpm_mode = SendMessage(h, CB_GETCURSEL, 0, 0); - ret = create_86f(fd_file_name, disk_sizes[disk_size], rpm_mode); - } else { - if (is_zip) - ret = create_zip_sector_image(fd_file_name, disk_sizes[disk_size], file_type, hdlg); - else - ret = create_sector_image(fd_file_name, disk_sizes[disk_size], file_type); - } - if (ret) { - if (is_zip) - ui_sb_mount_zip_img(fdd_id, sb_part, 0, fd_file_name); - else - ui_sb_mount_floppy_img(fdd_id, sb_part, 0, fd_file_name); - } else { - new_floppy_msgbox(hdlg, MBX_ERROR, (wchar_t *)IDS_4108); - return TRUE; - } - case IDCANCEL: - EndDialog(hdlg, 0); - plat_pause(0); - return TRUE; - - case IDC_CFILE: - if (!file_dlg_w(hdlg, plat_get_string(is_zip ? IDS_2055 : IDS_2062), L"", 1)) { - if (!wcschr(wopenfilestring, L'.')) { - if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) { - twcs = &wopenfilestring[wcslen(wopenfilestring)]; - twcs[0] = L'.'; - if (!is_zip && (filterindex == 3)) { - twcs[1] = L'8'; - twcs[2] = L'6'; - twcs[3] = L'f'; - } else { - twcs[1] = L'i'; - twcs[2] = L'm'; - twcs[3] = L'g'; - } - } - } - h = GetDlgItem(hdlg, IDC_EDIT_FILE_NAME); - f = _wfopen(wopenfilestring, L"rb"); - if (f != NULL) { - fclose(f); - if (new_floppy_msgbox(hdlg, MBX_QUESTION, (wchar_t *)IDS_4111) != 0) /* yes */ - return FALSE; - } - SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); - memset(fd_file_name, 0, sizeof(fd_file_name)); - wcscpy(fd_file_name, wopenfilestring); - h = GetDlgItem(hdlg, IDC_COMBO_DISK_SIZE); - if (!is_zip || zip_drives[fdd_id].is_250) - EnableWindow(h, TRUE); - wcs_len = wcslen(wopenfilestring); - ext_offs = wcs_len - 4; - ext = &(wopenfilestring[ext_offs]); - if (is_zip) { - if (((wcs_len >= 4) && !wcsicmp(ext, L".ZDI"))) - file_type = 1; - else - file_type = 0; - } else { - if (((wcs_len >= 4) && !wcsicmp(ext, L".FDI"))) - file_type = 1; - else if ((((wcs_len >= 4) && !wcsicmp(ext, L".86F")) || (filterindex == 3))) - file_type = 2; - else - file_type = 0; - } - h = GetDlgItem(hdlg, IDT_1751); - if (file_type == 2) { - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - } else { - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - h = GetDlgItem(hdlg, IDC_COMBO_RPM_MODE); - if (file_type == 2) { - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - } else { - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - h = GetDlgItem(hdlg, IDOK); - EnableWindow(h, TRUE); - return TRUE; - } else - return FALSE; - - default: - break; - } - break; - } - - return(FALSE); -} - - -void -NewFloppyDialogCreate(HWND hwnd, int id, int part) -{ - fdd_id = id & 0x7f; - sb_part = part; - is_zip = !!(id & 0x80); - DialogBox(hinstance, (LPCTSTR)DLG_NEW_FLOPPY, hwnd, NewFloppyDialogProcedure); -} diff --git a/backup code/win/win_settings - Cópia.c b/backup code/win/win_settings - Cópia.c deleted file mode 100644 index 1c1d58bff..000000000 --- a/backup code/win/win_settings - Cópia.c +++ /dev/null @@ -1,4443 +0,0 @@ -/* - * 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. - * - * Windows 86Box Settings dialog handler. - * - * Version: @(#)win_settings.c 1.0.51 2018/05/25 - * - * Author: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../config.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../machine/machine.h" -#include "../game/gameport.h" -#include "../lpt.h" -#include "../mouse.h" -#include "../scsi/scsi.h" -#include "../cdrom/cdrom.h" -#include "../disk/hdd.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../disk/zip.h" -#include "../floppy/fdd.h" -#include "../network/network.h" -#include "../sound/sound.h" -#include "../sound/midi.h" -#include "../sound/snd_dbopl.h" -#include "../sound/snd_mpu401.h" -#include "../video/video.h" -#include "../video/vid_voodoo.h" -#include "../plat.h" -#include "../plat_midi.h" -#include "../ui.h" -#include "win.h" - - -#define SETTINGS_PAGE_MACHINE 0 -#define SETTINGS_PAGE_VIDEO 1 -#define SETTINGS_PAGE_INPUT 2 -#define SETTINGS_PAGE_SOUND 3 -#define SETTINGS_PAGE_NETWORK 4 -#define SETTINGS_PAGE_PORTS 5 -#define SETTINGS_PAGE_PERIPHERALS 6 -#define SETTINGS_PAGE_HARD_DISKS 7 -#define SETTINGS_PAGE_FLOPPY_DRIVES 8 -#define SETTINGS_PAGE_OTHER_REMOVABLE_DEVICES 9 - -/* Icon, Bus, File, C, H, S, Size */ -#define C_COLUMNS_HARD_DISKS 6 - - -/* Machine category */ -static int temp_machine, temp_cpu_m, temp_cpu, temp_wait_states, temp_fpu, temp_sync; -static uint32_t temp_mem_size; -#ifdef USE_DYNAREC -static int temp_dynarec; -#endif - -/* Video category */ -static int temp_gfxcard, temp_voodoo; - -/* Input devices category */ -static int temp_mouse, temp_joystick; - -/* Sound category */ -static int temp_sound_card, temp_midi_device, temp_mpu401, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl_type; -static int temp_float; - -/* Network category */ -static int temp_net_type, temp_net_card; -static char temp_pcap_dev[520]; - -/* Ports category */ -static char temp_lpt_device_names[3][16]; -static int temp_serial[2], temp_lpt; - -/* Other peripherals category */ -static int temp_scsi_card, temp_ide_ter, temp_ide_qua; -static char temp_hdc_name[32]; -static char *hdc_names[32]; -static int temp_bugger; - -static uint8_t temp_deviceconfig; - -/* Hard disks category */ -static hard_disk_t temp_hdd[HDD_NUM]; - -/* Floppy drives category */ -static int temp_fdd_types[FDD_NUM]; -static int temp_fdd_turbo[FDD_NUM]; -static int temp_fdd_check_bpb[FDD_NUM]; - -/* Other removable devices category */ -static cdrom_drive_t temp_cdrom_drives[CDROM_NUM]; -static zip_drive_t temp_zip_drives[ZIP_NUM]; - -static HWND hwndParentDialog, hwndChildDialog; - -static uint32_t displayed_category = 0; - -extern int is486; -static int romstolist[ROM_MAX], listtomachine[ROM_MAX], romstomachine[ROM_MAX], machinetolist[ROM_MAX]; -static int settings_device_to_list[20], settings_list_to_device[20]; -static int settings_midi_to_list[20], settings_list_to_midi[20]; - -static int64_t max_spt = 63, max_hpc = 255, max_tracks = 266305; -static uint64_t mfm_tracking, esdi_tracking, xta_tracking, ide_tracking, scsi_tracking[16]; -static uint64_t size, selection = 127; -static int net_ignore_message = 0, next_free_id = 0; -static int hd_listview_items, hdc_id_to_listview_index[HDD_NUM]; -static int hdlv_current_sel, hard_disk_added = 0; -static int no_update = 0, existing = 0, chs_enabled = 0; -static int spt, hpc, tracks, ignore_change = 0; -static int fdlv_current_sel, cdlv_current_sel, zdlv_current_sel; -static int fd_ignore_change = 0, rd_ignore_change = 0; - -static hard_disk_t new_hdd, *hdd_ptr; - -static wchar_t hd_file_name[512]; - - -static BOOL -image_list_init(HWND hwndList, const uint8_t *icon_ids) -{ - HICON hiconItem; - HIMAGELIST hSmall; - - int i = 0; - - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); - - while(1) { - if (icon_ids[i] == 0) - break; - - hiconItem = LoadIcon(hinstance, (LPCWSTR) ((uint32_t) icon_ids[i])); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - i++; - } - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - - -/* Show a MessageBox dialog. This is nasty, I know. --FvK */ -static int -settings_msgbox(int type, void *arg) -{ - HWND h; - int i; - - h = hwndMain; - hwndMain = hwndParentDialog; - - i = ui_msgbox(type, arg); - - hwndMain = h; - - return(i); -} - - -/* This does the initial read of global variables into the temporary ones. */ -static void -win_settings_init(void) -{ - int i = 0; - - /* Machine category */ - temp_machine = machine; - temp_cpu_m = cpu_manufacturer; - temp_wait_states = cpu_waitstates; - temp_cpu = cpu; - temp_mem_size = mem_size; -#ifdef USE_DYNAREC - temp_dynarec = cpu_use_dynarec; -#endif - temp_fpu = enable_external_fpu; - temp_sync = enable_sync; - - /* Video category */ - temp_gfxcard = gfxcard; - temp_voodoo = voodoo_enabled; - - /* Input devices category */ - temp_mouse = mouse_type; - temp_joystick = joystick_type; - - /* Sound category */ - temp_sound_card = sound_card_current; - temp_midi_device = midi_device_current; - temp_mpu401 = mpu401_standalone_enable; - temp_SSI2001 = SSI2001; - temp_GAMEBLASTER = GAMEBLASTER; - temp_GUS = GUS; - temp_opl_type = opl_type; - temp_float = sound_is_float; - - /* Network category */ - temp_net_type = network_type; - memset(temp_pcap_dev, 0, sizeof(temp_pcap_dev)); - strcpy(temp_pcap_dev, network_host); - temp_net_card = network_card; - - /* Ports category */ - for (i = 0; i < 3; i++) - strncpy(temp_lpt_device_names[i], lpt_device_names[i], sizeof(temp_lpt_device_names[i]) - 1); - temp_serial[0] = serial_enabled[0]; - temp_serial[1] = serial_enabled[1]; - temp_lpt = lpt_enabled; - - /* Other peripherals category */ - temp_scsi_card = scsi_card_current; - strncpy(temp_hdc_name, hdc_name, sizeof(temp_hdc_name) - 1); - temp_ide_ter = ide_ter_enabled; - temp_ide_qua = ide_qua_enabled; - temp_bugger = bugger_enabled; - - mfm_tracking = xta_tracking = esdi_tracking = ide_tracking = 0; - for (i = 0; i < 16; i++) - scsi_tracking[i] = 0; - - /* Hard disks category */ - memcpy(temp_hdd, hdd, HDD_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDD_NUM; i++) { - if (hdd[i].bus == HDD_BUS_MFM) - mfm_tracking |= (1 << (hdd[i].mfm_channel << 3)); - else if (hdd[i].bus == HDD_BUS_XTA) - xta_tracking |= (1 << (hdd[i].xta_channel << 3)); - else if (hdd[i].bus == HDD_BUS_ESDI) - esdi_tracking |= (1 << (hdd[i].esdi_channel << 3)); - else if (hdd[i].bus == HDD_BUS_IDE) - ide_tracking |= (1 << (hdd[i].ide_channel << 3)); - else if (hdd[i].bus == HDD_BUS_SCSI) - scsi_tracking[hdd[i].scsi_id] |= (1 << (hdd[i].scsi_lun << 3)); - } - - /* Floppy drives category */ - for (i = 0; i < FDD_NUM; i++) { - temp_fdd_types[i] = fdd_get_type(i); - temp_fdd_turbo[i] = fdd_get_turbo(i); - temp_fdd_check_bpb[i] = fdd_get_check_bpb(i); - } - - /* Other removable devices category */ - memcpy(temp_cdrom_drives, cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); - for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI) - ide_tracking |= (2 << (cdrom_drives[i].ide_channel << 3)); - else if (cdrom_drives[i].bus_type == CDROM_BUS_SCSI) - scsi_tracking[cdrom_drives[i].scsi_device_id] |= (2 << (cdrom_drives[i].scsi_device_lun << 3)); - } - memcpy(temp_zip_drives, zip_drives, ZIP_NUM * sizeof(zip_drive_t)); - for (i = 0; i < ZIP_NUM; i++) { - if (zip_drives[i].bus_type == ZIP_BUS_ATAPI) - ide_tracking |= (4 << (zip_drives[i].ide_channel << 3)); - else if (zip_drives[i].bus_type == ZIP_BUS_SCSI) - scsi_tracking[zip_drives[i].scsi_device_id] |= (4 << (zip_drives[i].scsi_device_lun << 3)); - } - - temp_deviceconfig = 0; -} - - -/* This returns 1 if any variable has changed, 0 if not. */ -static int -win_settings_changed(void) -{ - int i = 0; - int j = 0; - - /* Machine category */ - i = i || (machine != temp_machine); - i = i || (cpu_manufacturer != temp_cpu_m); - i = i || (cpu_waitstates != temp_wait_states); - i = i || (cpu != temp_cpu); - i = i || (mem_size != temp_mem_size); -#ifdef USE_DYNAREC - i = i || (temp_dynarec != cpu_use_dynarec); -#endif - i = i || (temp_fpu != enable_external_fpu); - i = i || (temp_sync != enable_sync); - - /* Video category */ - i = i || (gfxcard != temp_gfxcard); - i = i || (voodoo_enabled != temp_voodoo); - - /* Input devices category */ - i = i || (mouse_type != temp_mouse); - i = i || (joystick_type != temp_joystick); - - /* Sound category */ - i = i || (sound_card_current != temp_sound_card); - i = i || (midi_device_current != temp_midi_device); - i = i || (mpu401_standalone_enable != temp_mpu401); - i = i || (SSI2001 != temp_SSI2001); - i = i || (GAMEBLASTER != temp_GAMEBLASTER); - i = i || (GUS != temp_GUS); - i = i || (opl_type != temp_opl_type); - i = i || (sound_is_float != temp_float); - - /* Network category */ - i = i || (network_type != temp_net_type); - i = i || strcmp(temp_pcap_dev, network_host); - i = i || (network_card != temp_net_card); - - /* Ports category */ - for (j = 0; j < 3; j++) - i = i || strncmp(temp_lpt_device_names[j], lpt_device_names[j], sizeof(temp_lpt_device_names[j]) - 1); - i = i || (temp_serial[0] != serial_enabled[0]); - i = i || (temp_serial[1] != serial_enabled[1]); - i = i || (temp_lpt != lpt_enabled); - - /* Peripherals category */ - i = i || (scsi_card_current != temp_scsi_card); - i = i || strncmp(temp_hdc_name, hdc_name, sizeof(temp_hdc_name) - 1); - i = i || (temp_ide_ter != ide_ter_enabled); - i = i || (temp_ide_qua != ide_qua_enabled); - i = i || (temp_bugger != bugger_enabled); - - /* Hard disks category */ - i = i || memcmp(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); - - /* Floppy drives category */ - for (j = 0; j < FDD_NUM; j++) { - i = i || (temp_fdd_types[j] != fdd_get_type(j)); - i = i || (temp_fdd_turbo[j] != fdd_get_turbo(j)); - i = i || (temp_fdd_check_bpb[j] != fdd_get_check_bpb(j)); - } - - /* Other removable devices category */ - i = i || memcmp(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); - i = i || memcmp(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t)); - - i = i || !!temp_deviceconfig; - - return i; -} - - -static int -settings_msgbox_reset(void) -{ - int changed, i = 0; - - changed = win_settings_changed(); - - if (changed) { - i = settings_msgbox(MBX_QUESTION, (wchar_t *)IDS_2051); - - if (i == 1) return(1); /* no */ - - if (i < 0) return(0); /* cancel */ - - return(2); /* yes */ - } else - return(1); -} - - -/* This saves the settings back to the global variables. */ -static void -win_settings_save(void) -{ - int i = 0; - - pc_reset_hard_close(); - - /* Machine category */ - machine = temp_machine; - romset = machine_getromset(); - cpu_manufacturer = temp_cpu_m; - cpu_waitstates = temp_wait_states; - cpu = temp_cpu; - mem_size = temp_mem_size; -#ifdef USE_DYNAREC - cpu_use_dynarec = temp_dynarec; -#endif - enable_external_fpu = temp_fpu; - enable_sync = temp_sync; - - /* Video category */ - gfxcard = temp_gfxcard; - voodoo_enabled = temp_voodoo; - - /* Input devices category */ - mouse_type = temp_mouse; - joystick_type = temp_joystick; - - /* Sound category */ - sound_card_current = temp_sound_card; - midi_device_current = temp_midi_device; - mpu401_standalone_enable = temp_mpu401; - SSI2001 = temp_SSI2001; - GAMEBLASTER = temp_GAMEBLASTER; - GUS = temp_GUS; - opl_type = temp_opl_type; - sound_is_float = temp_float; - - /* Network category */ - network_type = temp_net_type; - memset(network_host, '\0', sizeof(network_host)); - strcpy(network_host, temp_pcap_dev); - network_card = temp_net_card; - - /* Ports category */ - for (i = 0; i < 3; i++) - strncpy(lpt_device_names[i], temp_lpt_device_names[i], sizeof(temp_lpt_device_names[i]) - 1); - serial_enabled[0] = temp_serial[0]; - serial_enabled[1] = temp_serial[1]; - lpt_enabled = temp_lpt; - - /* Peripherals category */ - scsi_card_current = temp_scsi_card; - if (hdc_name) { - free(hdc_name); - hdc_name = NULL; - } - hdc_name = (char *) malloc(sizeof(temp_hdc_name)); - strncpy(hdc_name, temp_hdc_name, sizeof(temp_hdc_name) - 1); - hdc_init(hdc_name); - ide_ter_enabled = temp_ide_ter; - ide_qua_enabled = temp_ide_qua; - bugger_enabled = temp_bugger; - - /* Hard disks category */ - memcpy(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); - - /* Floppy drives category */ - for (i = 0; i < FDD_NUM; i++) { - fdd_set_type(i, temp_fdd_types[i]); - fdd_set_turbo(i, temp_fdd_turbo[i]); - fdd_set_check_bpb(i, temp_fdd_check_bpb[i]); - } - - /* Removable devices category */ - memcpy(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); - memcpy(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t)); - - /* Mark configuration as changed. */ - config_changed = 1; - - pc_reset_hard_init(); -} - - -static void -win_settings_machine_recalc_cpu(HWND hdlg) -{ - HWND h; - int cpu_type, temp_romset; -#ifdef USE_DYNAREC - int cpu_flags; -#endif - - temp_romset = machine_getromset_ex(temp_machine); - - h = GetDlgItem(hdlg, IDC_COMBO_WS); - cpu_type = machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if ((cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - -#ifdef USE_DYNAREC - h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); - cpu_flags = machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) && (cpu_flags & CPU_REQUIRES_DYNAREC)) - fatal("Attempting to select a CPU that requires the recompiler and does not support it at the same time\n"); - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) { - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC)) - temp_dynarec = 0; - if (cpu_flags & CPU_REQUIRES_DYNAREC) - temp_dynarec = 1; - SendMessage(h, BM_SETCHECK, temp_dynarec, 0); - EnableWindow(h, FALSE); - } else - EnableWindow(h, TRUE); -#endif - - h = GetDlgItem(hdlg, IDC_CHECK_FPU); - cpu_type = machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if ((cpu_type < CPU_i486DX) && (cpu_type >= CPU_286)) - EnableWindow(h, TRUE); - else if (cpu_type < CPU_286) { - temp_fpu = 0; - EnableWindow(h, FALSE); - } else { - temp_fpu = 1; - EnableWindow(h, FALSE); - } - SendMessage(h, BM_SETCHECK, temp_fpu, 0); -} - - -static void -win_settings_machine_recalc_cpu_m(HWND hdlg) -{ - HWND h; - int c, temp_romset; - LPTSTR lptsTemp; - char *stransi; - - temp_romset = machine_getromset_ex(temp_machine); - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_CPU); - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = 0; - while (machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[c].cpu_type != -1) { - stransi = (char *) machines[romstomachine[temp_romset]].cpu[temp_cpu_m].cpus[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); - c++; - } - EnableWindow(h, TRUE); - if (temp_cpu >= c) - temp_cpu = (c - 1); - SendMessage(h, CB_SETCURSEL, temp_cpu, 0); - - win_settings_machine_recalc_cpu(hdlg); - - free(lptsTemp); -} - - -static void -win_settings_machine_recalc_machine(HWND hdlg) -{ - HWND h; - int c, temp_romset; - LPTSTR lptsTemp; - const char *stransi; - UDACCEL accel; - - temp_romset = machine_getromset_ex(temp_machine); - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MACHINE); - if (machine_getdevice(temp_machine)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = 0; - while (machines[romstomachine[temp_romset]].cpu[c].cpus != NULL && c < 4) { - stransi = machines[romstomachine[temp_romset]].cpu[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); - c++; - } - EnableWindow(h, TRUE); - if (temp_cpu_m >= c) - temp_cpu_m = (c - 1); - SendMessage(h, CB_SETCURSEL, temp_cpu_m, 0); - EnableWindow(h, (c == 1) ? FALSE : TRUE); - - win_settings_machine_recalc_cpu_m(hdlg); - - h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETRANGE, 0, (machines[romstomachine[temp_romset]].min_ram << 16) | machines[romstomachine[temp_romset]].max_ram); - accel.nSec = 0; - accel.nInc = machines[romstomachine[temp_romset]].ram_granularity; - SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); - if (!(machines[romstomachine[temp_romset]].flags & MACHINE_AT) || (machines[romstomachine[temp_romset]].ram_granularity >= 128)) { - SendMessage(h, UDM_SETPOS, 0, temp_mem_size); - h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_2094)); - } else { - SendMessage(h, UDM_SETPOS, 0, temp_mem_size / 1024); - h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_2087)); - } - - free(lptsTemp); -} - - -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h, h2; - int c, d; - LPTSTR lptsTemp; - char *stransi; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); - for (c = 0; c < ROM_MAX; c++) - romstolist[c] = 0; - c = d = 0; - while (machines[c].id != -1) { - if (romspresent[machines[c].id]) { - stransi = (char *)machines[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - machinetolist[c] = d; - listtomachine[d] = c; - romstolist[machines[c].id] = d; - romstomachine[machines[c].id] = c; - d++; - } - c++; - } - SendMessage(h, CB_SETCURSEL, machinetolist[temp_machine], 0); - - h = GetDlgItem(hdlg, IDC_COMBO_WS); - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2099)); - - for (c = 0; c < 8; c++) { - wsprintf(lptsTemp, plat_get_string(2100), c); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - SendMessage(h, CB_SETCURSEL, temp_wait_states, 0); - -#ifdef USE_DYNAREC - h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); - SendMessage(h, BM_SETCHECK, temp_dynarec, 0); -#endif - - h = GetDlgItem(hdlg, IDC_MEMSPIN); - h2 = GetDlgItem(hdlg, IDC_MEMTEXT); - SendMessage(h, UDM_SETBUDDY, (WPARAM)h2, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_SYNC); - SendMessage(h, BM_SETCHECK, temp_sync, 0); - - win_settings_machine_recalc_machine(hdlg); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_MACHINE: - if (HIWORD(wParam) == CBN_SELCHANGE) { - h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); - temp_machine = listtomachine[SendMessage(h,CB_GETCURSEL,0,0)]; - - win_settings_machine_recalc_machine(hdlg); - } - break; - case IDC_COMBO_CPU_TYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) { - h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); - temp_cpu_m = SendMessage(h, CB_GETCURSEL, 0, 0); - - temp_cpu = 0; - win_settings_machine_recalc_cpu_m(hdlg); - } - break; - case IDC_COMBO_CPU: - if (HIWORD(wParam) == CBN_SELCHANGE) { - h = GetDlgItem(hdlg, IDC_COMBO_CPU); - temp_cpu = SendMessage(h, CB_GETCURSEL, 0, 0); - - win_settings_machine_recalc_cpu(hdlg); - } - break; - case IDC_CONFIGURE_MACHINE: - h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); - temp_machine = listtomachine[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)machine_getdevice(temp_machine)); - break; - } - - return FALSE; - - case WM_SAVESETTINGS: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *)malloc(512); - -#ifdef USE_DYNAREC - h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); - temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0); -#endif - - h=GetDlgItem(hdlg, IDC_CHECK_SYNC); - temp_sync = SendMessage(h, BM_GETCHECK, 0, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_FPU); - temp_fpu = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_WS); - temp_wait_states = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_MEMTEXT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - sscanf(stransi, "%u", &temp_mem_size); - temp_mem_size &= ~(machines[temp_machine].ram_granularity - 1); - if (temp_mem_size < machines[temp_machine].min_ram) - temp_mem_size = machines[temp_machine].min_ram; - else if (temp_mem_size > machines[temp_machine].max_ram) - temp_mem_size = machines[temp_machine].max_ram; - if ((machines[temp_machine].flags & MACHINE_AT) && (machines[temp_machine].ram_granularity < 128)) - temp_mem_size *= 1024; - free(stransi); - free(lptsTemp); - - default: - return FALSE; - } - - return FALSE; -} - - -static void -recalc_vid_list(HWND hdlg) -{ - HWND h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - int c = 0, d = 0; - int found_card = 0; - WCHAR szText[512]; - - SendMessage(h, CB_RESETCONTENT, 0, 0); - SendMessage(h, CB_SETCURSEL, 0, 0); - - while (1) { - /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !(machines[temp_machine].flags&MACHINE_VIDEO)) { - c++; - continue; - } - - char *s = video_card_getname(c); - - if (!s[0]) - break; - - if (video_card_available(c) && gfx_present[video_new_to_old(c)] && - device_is_valid(video_card_getdevice(c), machines[temp_machine].flags)) { - mbstowcs(szText, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - if (video_new_to_old(c) == temp_gfxcard) { - SendMessage(h, CB_SETCURSEL, d, 0); - found_card = 1; - } - - d++; - } - - c++; - } - if (!found_card) - SendMessage(h, CB_SETCURSEL, 0, 0); - EnableWindow(h, machines[temp_machine].fixed_gfxcard ? FALSE : TRUE); - - h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); - EnableWindow(h, (machines[temp_machine].flags & MACHINE_PCI) ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_BUTTON_VOODOO); - EnableWindow(h, ((machines[temp_machine].flags & MACHINE_PCI) && temp_voodoo) ? TRUE : FALSE); -} - - -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - LPTSTR lptsTemp; - char *stransi; - int gfx; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - recalc_vid_list(hdlg); - - h=GetDlgItem(hdlg, IDC_CHECK_VOODOO); - SendMessage(h, BM_SETCHECK, temp_voodoo, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - gfx = video_card_getid(stransi); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_VID); - if (video_card_has_config(gfx)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - free(stransi); - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_VIDEO: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - gfx = video_card_getid(stransi); - temp_gfxcard = video_new_to_old(gfx); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_VID); - if (video_card_has_config(gfx)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - free(stransi); - free(lptsTemp); - break; - - case IDC_CHECK_VOODOO: - h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); - temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_BUTTON_VOODOO); - EnableWindow(h, temp_voodoo ? TRUE : FALSE); - break; - - case IDC_BUTTON_VOODOO: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&voodoo_device); - break; - - case IDC_CONFIGURE_VID: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(stransi))); - - free(stransi); - free(lptsTemp); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, 512); - temp_gfxcard = video_new_to_old(video_card_getid(stransi)); - - h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); - temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); - - free(stransi); - free(lptsTemp); - - default: - return FALSE; - } - return FALSE; -} - - -static int -mouse_valid(int num, int m) -{ - const device_t *dev; - - if ((num == MOUSE_TYPE_INTERNAL) && - !(machines[m].flags & MACHINE_MOUSE)) return(0); - - dev = mouse_get_device(num); - return(device_is_valid(dev, machines[m].flags)); -} - - -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - wchar_t str[128]; - HWND h; - int c, d; - - switch (message) { - case WM_INITDIALOG: - h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); - c = d = 0; - for (c = 0; c < mouse_get_ndev(); c++) { - settings_device_to_list[c] = d; - - if (mouse_valid(c, temp_machine)) { - mbstowcs(str, mouse_get_name(c), sizeof_w(str)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)str); - - settings_list_to_device[d] = c; - d++; - } - } - - SendMessage(h, CB_SETCURSEL, settings_device_to_list[temp_mouse], 0); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MOUSE); - if (mouse_has_config(temp_mouse)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - c = 0; - while (joystick_get_name(c)) { - SendMessage(h, CB_ADDSTRING, 0, win_get_string(2105 + c)); - c++; - } - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_joystick, 0); - - h = GetDlgItem(hdlg, IDC_JOY1); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY2); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY3); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY4); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_MOUSE: - h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); - temp_mouse = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MOUSE); - if (mouse_has_config(temp_mouse)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - break; - - case IDC_CONFIGURE_MOUSE: - h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); - temp_mouse = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)mouse_get_device(temp_mouse)); - break; - - case IDC_COMBO_JOYSTICK: - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_JOY1); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY2); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY3); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY4); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); - break; - - case IDC_JOY1: - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - temp_deviceconfig |= joystickconfig_open(hdlg, 0, temp_joystick); - break; - - case IDC_JOY2: - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - temp_deviceconfig |= joystickconfig_open(hdlg, 1, temp_joystick); - break; - - case IDC_JOY3: - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - temp_deviceconfig |= joystickconfig_open(hdlg, 2, temp_joystick); - break; - - case IDC_JOY4: - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - temp_deviceconfig |= joystickconfig_open(hdlg, 3, temp_joystick); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); - temp_mouse = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - - default: - return FALSE; - } - return FALSE; -} - - -static int -mpu401_present(void) -{ - char *n; - - n = sound_card_get_internal_name(temp_sound_card); - if (n != NULL) { - if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) - return 1; - } - - return temp_mpu401 ? 1 : 0; -} - - -int -mpu401_standalone_allow(void) -{ - char *n, *md; - - n = sound_card_get_internal_name(temp_sound_card); - md = midi_device_get_internal_name(temp_midi_device); - if (n != NULL) { - if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) - return 0; - } - - if (md != NULL) { - if (!strcmp(md, "none")) - return 0; - } - - return 1; -} - - -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c, d; - LPTSTR lptsTemp; - const device_t *sound_dev; - char *s; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_SOUND); - c = d = 0; - while (1) { - s = sound_card_getname(c); - - if (!s[0]) - break; - - settings_device_to_list[c] = d; - - if (sound_card_available(c)) { - sound_dev = sound_card_getdevice(c); - - if (device_is_valid(sound_dev, machines[temp_machine].flags)) { - if (c == 0) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2112)); - else { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_device[d] = c; - d++; - } - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_device_to_list[temp_sound_card], 0); - - EnableWindow(h, d ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_SND); - EnableWindow(h, sound_card_has_config(temp_sound_card) ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - c = d = 0; - while (1) { - s = midi_device_getname(c); - - if (!s[0]) - break; - - settings_midi_to_list[c] = d; - - if (midi_device_available(c)) { - if (c == 0) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2112)); - else { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_midi[d] = c; - d++; - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_midi_to_list[temp_midi_device], 0); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MIDI); - if (midi_device_has_config(temp_midi_device)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_CHECK_MPU401); - SendMessage(h, BM_SETCHECK, temp_mpu401, 0); - EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); - EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); - - h=GetDlgItem(hdlg, IDC_CHECK_CMS); - SendMessage(h, BM_SETCHECK, temp_GAMEBLASTER, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_GUS); - SendMessage(h, BM_SETCHECK, temp_GUS, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_SSI); - SendMessage(h, BM_SETCHECK, temp_SSI2001, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_NUKEDOPL); - SendMessage(h, BM_SETCHECK, temp_opl_type, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_FLOAT); - SendMessage(h, BM_SETCHECK, temp_float, 0); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_SOUND: - h = GetDlgItem(hdlg, IDC_COMBO_SOUND); - temp_sound_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURE_SND); - if (sound_card_has_config(temp_sound_card)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_CHECK_MPU401); - SendMessage(h, BM_SETCHECK, temp_mpu401, 0); - EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); - EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); - break; - - case IDC_CONFIGURE_SND: - h = GetDlgItem(hdlg, IDC_COMBO_SOUND); - temp_sound_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card)); - break; - - case IDC_COMBO_MIDI: - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - temp_midi_device = settings_list_to_midi[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MIDI); - if (midi_device_has_config(temp_midi_device)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_CHECK_MPU401); - SendMessage(h, BM_SETCHECK, temp_mpu401, 0); - EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); - EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); - break; - - case IDC_CONFIGURE_MIDI: - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - temp_midi_device = settings_list_to_midi[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)midi_device_getdevice(temp_midi_device)); - break; - - case IDC_CHECK_MPU401: - h = GetDlgItem(hdlg, IDC_CHECK_MPU401); - temp_mpu401 = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); - EnableWindow(h, mpu401_present() ? TRUE : FALSE); - break; - - case IDC_CONFIGURE_MPU401: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&mpu401_device); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBO_SOUND); - temp_sound_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - temp_midi_device = settings_list_to_midi[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CHECK_MPU401); - temp_mpu401 = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECK_CMS); - temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECK_GUS); - temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECK_SSI); - temp_SSI2001 = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECK_NUKEDOPL); - temp_opl_type = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECK_FLOAT); - temp_float = SendMessage(h, BM_GETCHECK, 0, 0); - - default: - return FALSE; - } - return FALSE; -} - - -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_ports_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c, d, i; - char *s; - LPTSTR lptsTemp; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - - for (i = 0; i < 3; i++) { - h = GetDlgItem(hdlg, IDC_COMBO_LPT1 + i); - c = d = 0; - while (1) { - s = lpt_device_get_name(c); - - if (!s) - break; - - if (c == 0) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2112)); - else { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - if (!strcmp(temp_lpt_device_names[i], lpt_device_get_internal_name(c))) - d = c; - - c++; - } - SendMessage(h, CB_SETCURSEL, d, 0); - } - - h=GetDlgItem(hdlg, IDC_CHECK_SERIAL1); - SendMessage(h, BM_SETCHECK, temp_serial[0], 0); - - h=GetDlgItem(hdlg, IDC_CHECK_SERIAL2); - SendMessage(h, BM_SETCHECK, temp_serial[1], 0); - - h=GetDlgItem(hdlg, IDC_CHECK_PARALLEL); - SendMessage(h, BM_SETCHECK, temp_lpt, 0); - - free(lptsTemp); - - return TRUE; - - case WM_SAVESETTINGS: - for (i = 0; i < 3; i++) { - h = GetDlgItem(hdlg, IDC_COMBO_LPT1 + i); - c = SendMessage(h, CB_GETCURSEL, 0, 0); - strcpy(temp_lpt_device_names[i], lpt_device_get_internal_name(c)); - } - - h = GetDlgItem(hdlg, IDC_CHECK_SERIAL1); - temp_serial[0] = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECK_SERIAL2); - temp_serial[1] = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECK_PARALLEL); - temp_lpt = SendMessage(h, BM_GETCHECK, 0, 0); - - default: - return FALSE; - } - return FALSE; -} - - -static void -recalc_hdc_list(HWND hdlg, int machine, int use_selected_hdc) -{ - HWND h; - char *s, old_name[32]; - int valid, c, d; - - LPTSTR lptsTemp; - - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_HDC); - - valid = 0; - - if (use_selected_hdc) { - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (c != -1 && hdc_names[c]) - strncpy(old_name, hdc_names[c], sizeof(old_name) - 1); - else - strcpy(old_name, "none"); - } else - strncpy(old_name, temp_hdc_name, sizeof(old_name) - 1); - - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = d = 0; - while (1) { - s = hdc_get_name(c); - if (s[0] == 0) - break; - if (c==1 && !(machines[temp_machine].flags&MACHINE_HDC)) { - /* Skip "Internal" if machine doesn't have one. */ - c++; - continue; - } - if (!hdc_available(c) || !device_is_valid(hdc_get_device(c), machines[temp_machine].flags)) { - c++; - continue; - } - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - - hdc_names[d] = hdc_get_internal_name(c); - if (!strcmp(old_name, hdc_names[d])) { - SendMessage(h, CB_SETCURSEL, d, 0); - valid = 1; - } - c++; - d++; - } - - if (!valid) - SendMessage(h, CB_SETCURSEL, 0, 0); - - EnableWindow(h, d ? TRUE : FALSE); - - free(lptsTemp); -} - - -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c, d, temp_hdc_type; - LPTSTR lptsTemp; - const device_t *scsi_dev; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - - /*SCSI config*/ - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - c = d = 0; - while (1) { - char *s = scsi_card_getname(c); - - if (!s[0]) - break; - - settings_device_to_list[c] = d; - - if (scsi_card_available(c)) { - scsi_dev = scsi_card_getdevice(c); - - if (device_is_valid(scsi_dev, machines[temp_machine].flags)) { - if (c == 0) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2112)); - else { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_device[d] = c; - d++; - } - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_device_to_list[temp_scsi_card], 0); - - EnableWindow(h, d ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); - EnableWindow(h, scsi_card_has_config(temp_scsi_card) ? TRUE : FALSE); - - recalc_hdc_list(hdlg, temp_machine, 0); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_HDC); - EnableWindow(h, hdc_has_config(hdc_get_from_internal_name(temp_hdc_name)) ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_CHECK_IDE_TER); - EnableWindow(h, (machines[temp_machine].flags & MACHINE_AT) ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_BUTTON_IDE_TER); - EnableWindow(h, ((machines[temp_machine].flags & MACHINE_AT) && temp_ide_ter) ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_CHECK_IDE_QUA); - EnableWindow(h, (machines[temp_machine].flags & MACHINE_AT) ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_BUTTON_IDE_QUA); - EnableWindow(h, ((machines[temp_machine].flags & MACHINE_AT) && temp_ide_qua) ? TRUE : FALSE); - - h=GetDlgItem(hdlg, IDC_CHECK_IDE_TER); - SendMessage(h, BM_SETCHECK, temp_ide_ter, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_IDE_QUA); - SendMessage(h, BM_SETCHECK, temp_ide_qua, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_BUGGER); - SendMessage(h, BM_SETCHECK, temp_bugger, 0); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_HDC: - h = GetDlgItem(hdlg, IDC_COMBO_HDC); - temp_hdc_type = hdc_get_from_internal_name(hdc_names[SendMessage(h, CB_GETCURSEL, 0, 0)]); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_HDC); - EnableWindow(h, hdc_has_config(temp_hdc_type) ? TRUE : FALSE); - break; - - case IDC_CONFIGURE_HDC: - h = GetDlgItem(hdlg, IDC_COMBO_HDC); - temp_hdc_type = hdc_get_from_internal_name(hdc_names[SendMessage(h, CB_GETCURSEL, 0, 0)]); - - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)hdc_get_device(temp_hdc_type)); - break; - - case IDC_CONFIGURE_SCSI: - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - temp_scsi_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)scsi_card_getdevice(temp_scsi_card)); - break; - - case IDC_COMBO_SCSI: - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - temp_scsi_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); - if (scsi_card_has_config(temp_scsi_card)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - break; - - case IDC_CHECK_IDE_TER: - h = GetDlgItem(hdlg, IDC_CHECK_IDE_TER); - temp_ide_ter = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_BUTTON_IDE_TER); - EnableWindow(h, temp_ide_ter ? TRUE : FALSE); - break; - - case IDC_BUTTON_IDE_TER: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&ide_ter_device); - break; - - case IDC_CHECK_IDE_QUA: - h = GetDlgItem(hdlg, IDC_CHECK_IDE_QUA); - temp_ide_qua = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_BUTTON_IDE_QUA); - EnableWindow(h, temp_ide_qua ? TRUE : FALSE); - break; - - case IDC_BUTTON_IDE_QUA: - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&ide_qua_device); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBO_HDC); - c = SendMessage(h, CB_GETCURSEL, 0, 0); - if (hdc_names[c]) - strncpy(temp_hdc_name, hdc_names[c], sizeof(temp_hdc_name) - 1); - else - strcpy(temp_hdc_name, "none"); - - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - temp_scsi_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CHECK_IDE_TER); - temp_ide_ter = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECK_IDE_QUA); - temp_ide_qua = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECK_BUGGER); - temp_bugger = SendMessage(h, BM_GETCHECK, 0, 0); - - default: - return FALSE; - } - return FALSE; -} - - -static void network_recalc_combos(HWND hdlg) -{ - HWND h; - - net_ignore_message = 1; - - h = GetDlgItem(hdlg, IDC_COMBO_PCAP); - EnableWindow(h, (temp_net_type == NET_TYPE_PCAP) ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_COMBO_NET); - if (temp_net_type == NET_TYPE_SLIRP) - EnableWindow(h, TRUE); - else if ((temp_net_type == NET_TYPE_PCAP) && - (network_dev_to_id(temp_pcap_dev) > 0)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_NET); - if (network_card_has_config(temp_net_card) && - (temp_net_type == NET_TYPE_SLIRP)) - EnableWindow(h, TRUE); - else if (network_card_has_config(temp_net_card) && - (temp_net_type == NET_TYPE_PCAP) && - (network_dev_to_id(temp_pcap_dev) > 0)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - net_ignore_message = 0; -} - - -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c, d; - LPTSTR lptsTemp; - char *s; - - switch (message) { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"None"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"PCap"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"SLiRP"); - SendMessage(h, CB_SETCURSEL, temp_net_type, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_PCAP); - if (temp_net_type == NET_TYPE_PCAP) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_COMBO_PCAP); - for (c = 0; c < network_ndev; c++) { - mbstowcs(lptsTemp, network_devs[c].description, strlen(network_devs[c].description) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - SendMessage(h, CB_SETCURSEL, network_dev_to_id(temp_pcap_dev), 0); - - /*NIC config*/ - h = GetDlgItem(hdlg, IDC_COMBO_NET); - c = d = 0; - while (1) { - s = network_card_getname(c); - - if (s[0] == '\0') - break; - - settings_device_to_list[c] = d; - - if (network_card_available(c) && device_is_valid(network_card_getdevice(c), machines[temp_machine].flags)) { - if (c == 0) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(2112)); - else { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_device[d] = c; - d++; - } - - c++; - } - - SendMessage(h, CB_SETCURSEL, settings_device_to_list[temp_net_card], 0); - EnableWindow(h, d ? TRUE : FALSE); - network_recalc_combos(hdlg); - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COMBO_NET_TYPE: - if (net_ignore_message) - return FALSE; - - h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); - temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); - - network_recalc_combos(hdlg); - break; - - case IDC_COMBO_PCAP: - if (net_ignore_message) - return FALSE; - - h = GetDlgItem(hdlg, IDC_COMBO_PCAP); - memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); - strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); - - network_recalc_combos(hdlg); - break; - - case IDC_COMBO_NET: - if (net_ignore_message) - return FALSE; - - h = GetDlgItem(hdlg, IDC_COMBO_NET); - temp_net_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - network_recalc_combos(hdlg); - break; - - case IDC_CONFIGURE_NET: - if (net_ignore_message) - return FALSE; - - h = GetDlgItem(hdlg, IDC_COMBO_NET); - temp_net_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - temp_deviceconfig |= deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_net_card)); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); - temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_PCAP); - memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); - strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); - - h = GetDlgItem(hdlg, IDC_COMBO_NET); - temp_net_card = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - default: - return FALSE; - } - - return FALSE; -} - - -static void -normalize_hd_list() -{ - hard_disk_t ihdd[HDD_NUM]; - int i, j; - - j = 0; - memset(ihdd, 0x00, HDD_NUM * sizeof(hard_disk_t)); - - for (i = 0; i < HDD_NUM; i++) { - if (temp_hdd[i].bus != HDD_BUS_DISABLED) { - memcpy(&(ihdd[j]), &(temp_hdd[i]), sizeof(hard_disk_t)); - j++; - } - } - - memcpy(temp_hdd, ihdd, HDD_NUM * sizeof(hard_disk_t)); -} - - -static int -get_selected_hard_disk(HWND hdlg) -{ - int hard_disk = -1; - int i, j = 0; - HWND h; - - if (hd_listview_items == 0) - return 0; - - for (i = 0; i < hd_listview_items; i++) { - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - hard_disk = i; - } - - return hard_disk; -} - - -static void -add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - HWND h; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - for (i = 0; i < 5; i++) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_4352 + i)); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - for (i = 0; i < 2; i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - for (i = 0; i < 16; i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4098), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - for (i = 0; i < 8; i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4098), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - for (i = 0; i < 8; i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - free(lptsTemp); -} - - -static uint8_t -next_free_binary_channel(uint64_t *tracking) -{ - int64_t i; - - for (i = 0; i < 2; i++) { - if (!(*tracking & (0xffLL << (i << 3LL)))) - return i; - } - - return 2; -} - - -static uint8_t -next_free_ide_channel(void) -{ - int64_t i; - - for (i = 0; i < 8; i++) { - if (!(ide_tracking & (0xffLL << (i << 3LL)))) - return i; - } - - return 7; -} - - -static void -next_free_scsi_id_and_lun(uint8_t *id, uint8_t *lun) -{ - int64_t i, j; - - for (j = 0; j < 8; j++) { - for (i = 0; i < 16; i++) { - if (!(scsi_tracking[i] & (0xffLL << (j << 3LL)))) { - *id = i; - *lun = j; - return; - } - } - } - - *id = 6; - *lun = 7; -} - - -static void -recalc_location_controls(HWND hdlg, int is_add_dlg, int assign_id) -{ - int i = 0; - HWND h; - - int bus = 0; - - for (i = IDT_1722; i <= IDT_1724; i++) { - h = GetDlgItem(hdlg, i); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - if ((hd_listview_items > 0) || is_add_dlg) { - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - bus = SendMessage(h, CB_GETCURSEL, 0, 0); - bus++; - - switch(bus) { - case HDD_BUS_MFM: /* MFM */ - h = GetDlgItem(hdlg, IDT_1722); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - if (assign_id) - temp_hdd[hdlv_current_sel].mfm_channel = next_free_binary_channel(&mfm_tracking); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.mfm_channel : temp_hdd[hdlv_current_sel].mfm_channel, 0); - break; - case HDD_BUS_XTA: /* XTA */ - h = GetDlgItem(hdlg, IDT_1722); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - if (assign_id) - temp_hdd[hdlv_current_sel].xta_channel = next_free_binary_channel(&xta_tracking); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.xta_channel : temp_hdd[hdlv_current_sel].xta_channel, 0); - break; - case HDD_BUS_ESDI: /* ESDI */ - h = GetDlgItem(hdlg, IDT_1722); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - if (assign_id) - temp_hdd[hdlv_current_sel].esdi_channel = next_free_binary_channel(&esdi_tracking); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.esdi_channel : temp_hdd[hdlv_current_sel].esdi_channel, 0); - break; - case HDD_BUS_IDE: /* IDE */ - h = GetDlgItem(hdlg, IDT_1722); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - if (assign_id) - temp_hdd[hdlv_current_sel].ide_channel = next_free_ide_channel(); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.ide_channel : temp_hdd[hdlv_current_sel].ide_channel, 0); - break; - case HDD_BUS_SCSI: /* SCSI */ - h = GetDlgItem(hdlg, IDT_1723); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDT_1724); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - if (assign_id) - next_free_scsi_id_and_lun((uint8_t *) &temp_hdd[hdlv_current_sel].scsi_id, (uint8_t *) &temp_hdd[hdlv_current_sel].scsi_lun); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.scsi_id : temp_hdd[hdlv_current_sel].scsi_id, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdd.scsi_lun : temp_hdd[hdlv_current_sel].scsi_lun, 0); - break; - } - } - - if ((hd_listview_items == 0) && !is_add_dlg) { - h = GetDlgItem(hdlg, IDT_1721); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); - } else { - h = GetDlgItem(hdlg, IDT_1721); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - } -} - - -static int -bus_full(uint64_t *tracking, int count) -{ - int full = 0; - switch(count) { - case 2: - default: - full = (*tracking & 0xFF00LL); - full = full && (*tracking & 0x00FFLL); - return full; - case 8: - full = (*tracking & 0xFF00000000000000LL); - full = full && (*tracking & 0x00FF000000000000LL); - full = full && (*tracking & 0x0000FF0000000000LL); - full = full && (*tracking & 0x000000FF00000000LL); - full = full && (*tracking & 0x00000000FF000000LL); - full = full && (*tracking & 0x0000000000FF0000LL); - full = full && (*tracking & 0x000000000000FF00LL); - full = full && (*tracking & 0x00000000000000FFLL); - return full; - } -} - - -static void -recalc_next_free_id(HWND hdlg) -{ - HWND h; - int i, enable_add = 0; - int c_mfm = 0, c_esdi = 0; - int c_xta = 0, c_ide = 0; - int c_scsi = 0; - - next_free_id = -1; - - for (i = 0; i < HDD_NUM; i++) { - if (temp_hdd[i].bus == HDD_BUS_MFM) - c_mfm++; - else if (temp_hdd[i].bus == HDD_BUS_ESDI) - c_esdi++; - else if (temp_hdd[i].bus == HDD_BUS_XTA) - c_xta++; - else if (temp_hdd[i].bus == HDD_BUS_IDE) - c_ide++; - else if (temp_hdd[i].bus == HDD_BUS_SCSI) - c_scsi++; - } - - for (i = 0; i < HDD_NUM; i++) { - if (temp_hdd[i].bus == HDD_BUS_DISABLED) { - next_free_id = i; - break; - } - } - - enable_add = enable_add || (next_free_id >= 0); - enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_esdi < ESDI_NUM) || (c_xta < XTA_NUM) || - (c_ide < IDE_NUM) || (c_scsi < SCSI_NUM)); - enable_add = enable_add && !bus_full(&mfm_tracking, 2); - enable_add = enable_add && !bus_full(&esdi_tracking, 2); - enable_add = enable_add && !bus_full(&xta_tracking, 2); - enable_add = enable_add && !bus_full(&ide_tracking, 8); - for (i = 0; i < 16; i++) - enable_add = enable_add && !bus_full(&(scsi_tracking[i]), 8); - - h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD_NEW); - EnableWindow(h, enable_add ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD); - EnableWindow(h, enable_add ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_BUTTON_HDD_REMOVE); - EnableWindow(h, ((c_mfm == 0) && (c_esdi == 0) && (c_xta == 0) && (c_ide == 0) && (c_scsi == 0)) ? - FALSE : TRUE); -} - - -static void -win_settings_hard_disks_update_item(HWND hwndList, int i, int column) -{ - LVITEM lvI; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = column; - lvI.iItem = i; - - if (column == 0) { - switch(temp_hdd[i].bus) { - case HDD_BUS_MFM: - wsprintf(szText, plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1); - break; - case HDD_BUS_XTA: - wsprintf(szText, plat_get_string(IDS_4609), temp_hdd[i].xta_channel >> 1, temp_hdd[i].xta_channel & 1); - break; - case HDD_BUS_ESDI: - wsprintf(szText, plat_get_string(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1); - break; - case HDD_BUS_IDE: - wsprintf(szText, plat_get_string(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); - break; - case HDD_BUS_SCSI: - wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].scsi_id, temp_hdd[i].scsi_lun); - break; - } - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 1) { - lvI.pszText = temp_hdd[i].fn; - lvI.iImage = 0; - } else if (column == 2) { - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks); - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 3) { - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].hpc); - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 4) { - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].spt); - lvI.pszText = szText; - lvI.iImage = 0; - } else if (column == 5) { - wsprintf(szText, plat_get_string(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11); - lvI.pszText = szText; - lvI.iImage = 0; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -} - - -static BOOL -win_settings_hard_disks_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i, j = 0; - WCHAR szText[256]; - - hd_listview_items = 0; - hdlv_current_sel = -1; - - ListView_DeleteAllItems(hwndList); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < HDD_NUM; i++) { - if (temp_hdd[i].bus > 0) { - hdc_id_to_listview_index[i] = j; - lvI.iSubItem = 0; - switch(temp_hdd[i].bus) { - case HDD_BUS_MFM: - wsprintf(szText, plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1); - break; - case HDD_BUS_XTA: - wsprintf(szText, plat_get_string(IDS_4609), temp_hdd[i].xta_channel >> 1, temp_hdd[i].xta_channel & 1); - break; - case HDD_BUS_ESDI: - wsprintf(szText, plat_get_string(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1); - break; - case HDD_BUS_IDE: - wsprintf(szText, plat_get_string(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1); - break; - case HDD_BUS_SCSI: - wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].scsi_id, temp_hdd[i].scsi_lun); - break; - } - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - lvI.pszText = temp_hdd[i].fn; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 2; - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 3; - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].hpc); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 4; - wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].spt); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 5; - wsprintf(szText, plat_get_string(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - j++; - } else - hdc_id_to_listview_index[i] = -1; - } - - hd_listview_items = j; - - return TRUE; -} - - -static BOOL -win_settings_hard_disks_init_columns(HWND hwndList) -{ - LVCOLUMN lvc; - int iCol; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - for (iCol = 0; iCol < C_COLUMNS_HARD_DISKS; iCol++) { - lvc.iSubItem = iCol; - lvc.pszText = plat_get_string(IDS_2082 + iCol); - - switch(iCol) { - case 0: /* Bus */ - lvc.cx = 135; - lvc.fmt = LVCFMT_LEFT; - break; - case 2: /* Cylinders */ - lvc.cx = 41; - lvc.fmt = LVCFMT_RIGHT; - break; - case 3: /* Heads */ - case 4: /* Sectors */ - lvc.cx = 25; - lvc.fmt = LVCFMT_RIGHT; - break; - case 1: /* File */ - lvc.cx = 150; - lvc.fmt = LVCFMT_LEFT; - break; - case 5: /* Size (MB) 8 */ - lvc.cx = 41; - lvc.fmt = LVCFMT_RIGHT; - break; - } - - if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1) - return FALSE; - } - - return TRUE; -} - - -static void -get_edit_box_contents(HWND hdlg, int id, uint32_t *val) -{ - HWND h; - WCHAR szText[256]; - char stransi[256]; - - h = GetDlgItem(hdlg, id); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) szText); - wcstombs(stransi, szText, 256); - sscanf(stransi, "%u", val); -} - - -static void -get_combo_box_selection(HWND hdlg, int id, uint32_t *val) -{ - HWND h; - - h = GetDlgItem(hdlg, id); - *val = SendMessage(h, CB_GETCURSEL, 0, 0); -} - - -static void -set_edit_box_contents(HWND hdlg, int id, uint32_t val) -{ - HWND h; - WCHAR szText[256]; - - h = GetDlgItem(hdlg, id); - wsprintf(szText, plat_get_string(IDS_2115), val); - SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText); -} - - -static int hdconf_initialize_hdt_combo(HWND hdlg) -{ - HWND h; - int i = 0; - uint64_t temp_size = 0; - uint32_t size_mb = 0; - WCHAR szText[256]; - - selection = 127; - - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - for (i = 0; i < 127; i++) { - temp_size = hdd_table[i][0] * hdd_table[i][1] * hdd_table[i][2]; - size_mb = (uint32_t) (temp_size >> 11LL); - wsprintf(szText, plat_get_string(IDS_2116), size_mb, hdd_table[i][0], hdd_table[i][1], hdd_table[i][2]); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - if ((tracks == (int) hdd_table[i][0]) && (hpc == (int) hdd_table[i][1]) && - (spt == (int) hdd_table[i][2])) - selection = i; - } - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_4100)); - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_4101)); - SendMessage(h, CB_SETCURSEL, selection, 0); - return selection; -} - - -static void -recalc_selection(HWND hdlg) -{ - HWND h; - int i = 0; - - selection = 127; - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - for (i = 0; i < 127; i++) { - if ((tracks == (int) hdd_table[i][0]) && - (hpc == (int) hdd_table[i][1]) && - (spt == (int) hdd_table[i][2])) - selection = i; - } - if ((selection == 127) && (hpc == 16) && (spt == 63)) - selection = 128; - SendMessage(h, CB_SETCURSEL, selection, 0); -} - - -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - FILE *f; - uint32_t temp, i = 0, sector_size = 512; - uint32_t zero = 0, base = 0x1000; - uint64_t signature = 0xD778A82044445459ll; - uint64_t r = 0; - char buf[512], *big_buf; - int b = 0; - uint8_t channel = 0; - uint8_t id = 0, lun = 0; - wchar_t *twcs; - - switch (message) { - case WM_INITDIALOG: - memset(hd_file_name, 0, sizeof(hd_file_name)); - - hdd_ptr = &(temp_hdd[next_free_id]); - - SetWindowText(hdlg, plat_get_string((existing & 1) ? IDS_4103 : IDS_4102)); - - no_update = 1; - spt = (existing & 1) ? 0 : 17; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - hpc = (existing & 1) ? 0 : 15; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - tracks = (existing & 1) ? 0 : 1023; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20LL)); - hdconf_initialize_hdt_combo(hdlg); - if (existing & 1) { - h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - EnableWindow(h, FALSE); - chs_enabled = 0; - } else - chs_enabled = 1; - add_locations(hdlg); - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - hdd_ptr->bus = HDD_BUS_IDE; - max_spt = 63; - max_hpc = 255; - SendMessage(h, CB_SETCURSEL, hdd_ptr->bus, 0); - max_tracks = 266305; - recalc_location_controls(hdlg, 1, 0); - - channel = next_free_ide_channel(); - next_free_scsi_id_and_lun(&id, &lun); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - SendMessage(h, CB_SETCURSEL, id, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - SendMessage(h, CB_SETCURSEL, lun, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - SendMessage(h, CB_SETCURSEL, channel, 0); - - new_hdd.mfm_channel = next_free_binary_channel(&mfm_tracking); - new_hdd.esdi_channel = next_free_binary_channel(&esdi_tracking); - new_hdd.xta_channel = next_free_binary_channel(&xta_tracking); - new_hdd.ide_channel = channel; - new_hdd.scsi_id = id; - new_hdd.scsi_lun = lun; - - h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDT_1752); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - no_update = 0; - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - hdd_ptr->bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - - /* Make sure no file name is allowed with removable SCSI hard disks. */ - if (wcslen(hd_file_name) == 0) { - hdd_ptr->bus = HDD_BUS_DISABLED; - settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4112); - return TRUE; - } - - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(hdd_ptr->spt)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(hdd_ptr->hpc)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(hdd_ptr->tracks)); - spt = hdd_ptr->spt; - hpc = hdd_ptr->hpc; - tracks = hdd_ptr->tracks; - - switch(hdd_ptr->bus) { - case HDD_BUS_MFM: - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - hdd_ptr->mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - break; - case HDD_BUS_ESDI: - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - hdd_ptr->esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - break; - case HDD_BUS_XTA: - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - hdd_ptr->xta_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - break; - case HDD_BUS_IDE: - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - hdd_ptr->ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - break; - case HDD_BUS_SCSI: - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - hdd_ptr->scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - hdd_ptr->scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - break; - } - - memset(hdd_ptr->fn, 0, sizeof(hdd_ptr->fn)); - wcscpy(hdd_ptr->fn, hd_file_name); - - sector_size = 512; - - if (!(existing & 1) && (wcslen(hd_file_name) > 0)) { - f = _wfopen(hd_file_name, L"wb"); - - if (image_is_hdi(hd_file_name)) { - if (size >= 0x100000000ll) { - fclose(f); - settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4104); - return TRUE; - } - - fwrite(&zero, 1, 4, f); /* 00000000: Zero/unknown */ - fwrite(&zero, 1, 4, f); /* 00000004: Zero/unknown */ - fwrite(&base, 1, 4, f); /* 00000008: Offset at which data starts */ - fwrite(&size, 1, 4, f); /* 0000000C: Full size of the data (32-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ - - for (i = 0; i < 0x3f8; i++) - fwrite(&zero, 1, 4, f); - } else if (image_is_hdx(hd_file_name, 0)) { - if (size > 0xffffffffffffffffll) { - fclose(f); - settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4105); - return TRUE; - } - - fwrite(&signature, 1, 8, f); /* 00000000: Signature */ - fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ - fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ - fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ - } - - memset(buf, 0, 512); - - r = size >> 20; - size &= 0xfffff; - - if (size || r) { - h = GetDlgItem(hdlg, IDT_1731); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_CFILE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) r); - SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); - - h = GetDlgItem(hdlg, IDT_1752); - EnableWindow(h, TRUE); - ShowWindow(h, SW_SHOW); - } - - if (size) { - fwrite(buf, 1, size, f); - SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); - } - - if (r) { - big_buf = (char *) malloc(1048576); - memset(big_buf, 0, 1048576); - for (i = 0; i < r; i++) { - fwrite(big_buf, 1, 1048576, f); - SendMessage(h, PBM_SETPOS, (WPARAM) (size + 1), (LPARAM) 0); - } - free(big_buf); - } - - fclose(f); - settings_msgbox(MBX_INFO, (wchar_t *)IDS_4113); - } - - hard_disk_added = 1; - EndDialog(hdlg, 0); - return TRUE; - - case IDCANCEL: - hard_disk_added = 0; - hdd_ptr->bus = HDD_BUS_DISABLED; - EndDialog(hdlg, 0); - return TRUE; - - case IDC_CFILE: - if (!file_dlg_w(hdlg, plat_get_string(IDS_4106), L"", !(existing & 1))) { - if (!wcschr(wopenfilestring, L'.')) { - if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) { - twcs = &wopenfilestring[wcslen(wopenfilestring)]; - twcs[0] = L'.'; - twcs[1] = L'i'; - twcs[2] = L'm'; - twcs[3] = L'g'; - } - } - - if (!(existing & 1)) { - f = _wfopen(wopenfilestring, L"rb"); - if (f != NULL) { - fclose(f); - if (settings_msgbox(MBX_QUESTION, (wchar_t *)IDS_4111) != 0) /* yes */ - return FALSE; - } - } - - f = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb"); - if (f == NULL) { -hdd_add_file_open_error: - settings_msgbox(MBX_ERROR, (existing & 1) ? (wchar_t *)IDS_4107 : (wchar_t *)IDS_4108); - return TRUE; - } - if (existing & 1) { - if (image_is_hdi(wopenfilestring) || image_is_hdx(wopenfilestring, 1)) { - fseeko64(f, 0x10, SEEK_SET); - fread(§or_size, 1, 4, f); - if (sector_size != 512) { - settings_msgbox(MBX_ERROR, (wchar_t *)IDS_4109); - fclose(f); - return TRUE; - } - spt = hpc = tracks = 0; - fread(&spt, 1, 4, f); - fread(&hpc, 1, 4, f); - fread(&tracks, 1, 4, f); - } else { - fseeko64(f, 0, SEEK_END); - size = ftello64(f); - fclose(f); - if (((size % 17) == 0) && (size <= 142606336)) { - spt = 17; - if (size <= 26738688) - hpc = 4; - else if (((size % 3072) == 0) && (size <= 53477376)) - hpc = 6; - else { - for (i = 5; i < 16; i++) { - if (((size % (i << 9)) == 0) && (size <= ((i * 17) << 19))) - break; - if (i == 5) - i++; - } - hpc = i; - } - } else { - spt = 63; - hpc = 16; - } - - tracks = ((size >> 9) / hpc) / spt; - } - - if ((spt > max_spt) || (hpc > max_hpc) || (tracks > max_tracks)) - goto hdd_add_file_open_error; - no_update = 1; - - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - recalc_selection(hdlg); - - h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - EnableWindow(h, TRUE); - - chs_enabled = 1; - - no_update = 0; - } else - fclose(f); - } - - h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); - memset(hd_file_name, 0, sizeof(hd_file_name)); - wcscpy(hd_file_name, wopenfilestring); - - return TRUE; - - case IDC_EDIT_HD_CYL: - if (no_update) - return FALSE; - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &temp); - if (tracks != (int64_t) temp) { - tracks = temp; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) { - tracks = max_tracks; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_EDIT_HD_HPC: - if (no_update) - return FALSE; - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &temp); - if (hpc != (int64_t) temp) { - hpc = temp; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (hpc > max_hpc) { - hpc = max_hpc; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_EDIT_HD_SPT: - if (no_update) - return FALSE; - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &temp); - if (spt != (int64_t) temp) { - spt = temp; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (spt > max_spt) { - spt = max_spt; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_EDIT_HD_SIZE: - if (no_update) - return FALSE; - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, &temp); - if (temp != (uint32_t) (size >> 20)) { - size = ((uint64_t) temp) << 20LL; - tracks = (((uint32_t) (size >> 9)) / hpc) / spt; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) { - tracks = max_tracks; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_COMBO_HD_TYPE: - if (no_update) - return FALSE; - - no_update = 1; - get_combo_box_selection(hdlg, IDC_COMBO_HD_TYPE, &temp); - if ((temp != selection) && (temp != 127) && (temp != 128)) { - selection = temp; - tracks = hdd_table[selection][0]; - hpc = hdd_table[selection][1]; - spt = hdd_table[selection][2]; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - } else if ((temp != selection) && (temp == 127)) - selection = temp; - else if ((temp != selection) && (temp == 128)) { - selection = temp; - hpc = 16; - spt = 63; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - } - - if (spt > max_spt) { - spt = max_spt; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (hpc > max_hpc) { - hpc = max_hpc; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) { - tracks = max_tracks; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - no_update = 0; - break; - - case IDC_COMBO_HD_BUS: - if (no_update) - return FALSE; - - no_update = 1; - recalc_location_controls(hdlg, 1, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - b = SendMessage(h,CB_GETCURSEL,0,0) + 1; - if (b == hdd_ptr->bus) - goto hd_add_bus_skip; - - hdd_ptr->bus = b; - - switch(hdd_ptr->bus) { - case HDD_BUS_DISABLED: - default: - max_spt = max_hpc = max_tracks = 0; - break; - case HDD_BUS_MFM: - max_spt = 17; - max_hpc = 15; - max_tracks = 1023; - break; - case HDD_BUS_ESDI: - case HDD_BUS_XTA: - max_spt = 63; - max_hpc = 16; - max_tracks = 1023; - break; - case HDD_BUS_IDE: - max_spt = 63; - max_hpc = 255; - max_tracks = 266305; - break; - case HDD_BUS_SCSI: - max_spt = 99; - max_hpc = 255; - max_tracks = 266305; - break; - } - - if (!chs_enabled) { - h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - EnableWindow(h, FALSE); - } - - if (spt > max_spt) { - spt = max_spt; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (hpc > max_hpc) { - hpc = max_hpc; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - - if (tracks > max_tracks) { - tracks = max_tracks; - size = (tracks * hpc * spt) << 9LL; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20)); - recalc_selection(hdlg); - } - -hd_add_bus_skip: - no_update = 0; - break; - } - - return FALSE; - } - - return FALSE; -} - - -int -hard_disk_was_added(void) -{ - return hard_disk_added; -} - - -void -hard_disk_add_open(HWND hwnd, int is_existing) -{ - existing = is_existing; - hard_disk_added = 0; - DialogBox(hinstance, (LPCWSTR)DLG_CFG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); -} - - -static void -hard_disk_track(uint8_t id) -{ - switch(temp_hdd[id].bus) { - case HDD_BUS_MFM: - mfm_tracking |= (1 << (temp_hdd[id].mfm_channel << 3)); - break; - case HDD_BUS_ESDI: - esdi_tracking |= (1 << (temp_hdd[id].esdi_channel << 3)); - break; - case HDD_BUS_XTA: - xta_tracking |= (1 << (temp_hdd[id].xta_channel << 3)); - break; - case HDD_BUS_IDE: - ide_tracking |= (1 << (temp_hdd[id].ide_channel << 3)); - break; - case HDD_BUS_SCSI: - scsi_tracking[temp_hdd[id].scsi_id] |= (1 << (temp_hdd[id].scsi_lun << 3)); - break; - } -} - - -static void -hard_disk_untrack(uint8_t id) -{ - switch(temp_hdd[id].bus) { - case HDD_BUS_MFM: - mfm_tracking &= ~(1 << (temp_hdd[id].mfm_channel << 3)); - break; - case HDD_BUS_ESDI: - esdi_tracking &= ~(1 << (temp_hdd[id].esdi_channel << 3)); - break; - case HDD_BUS_XTA: - xta_tracking &= ~(1 << (temp_hdd[id].xta_channel << 3)); - break; - case HDD_BUS_IDE: - ide_tracking &= ~(1 << (temp_hdd[id].ide_channel << 3)); - break; - case HDD_BUS_SCSI: - scsi_tracking[temp_hdd[id].scsi_id] &= ~(1 << (temp_hdd[id].scsi_lun << 3)); - break; - } -} - - -static void -hard_disk_track_all(void) -{ - int i; - - for (i = 0; i < HDD_NUM; i++) - hard_disk_track(i); -} - - -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int old_sel = 0, b = 0, assign = 0; - const uint8_t hd_icons[2] = { 64, 0 }; - - switch (message) { - case WM_INITDIALOG: - ignore_change = 1; - - normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. - This will cause an emulator reset prompt on the first opening of this category with a messy hard disk list - (which can only happen by manually editing the configuration file). */ - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_init_columns(h); - image_list_init(h, (const uint8_t *) hd_icons); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - add_locations(hdlg); - if (hd_listview_items > 0) { - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - hdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdd[0].bus - 1, 0); - } else - hdlv_current_sel = -1; - recalc_location_controls(hdlg, 0, 0); - - ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if ((hd_listview_items == 0) || ignore_change) - return FALSE; - - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_HARD_DISKS)) { - old_sel = hdlv_current_sel; - hdlv_current_sel = get_selected_hard_disk(hdlg); - if (hdlv_current_sel == old_sel) - return FALSE; - else if (hdlv_current_sel == -1) { - ignore_change = 1; - hdlv_current_sel = old_sel; - ListView_SetItemState(h, hdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - ignore_change = 0; - return FALSE; - } - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdd[hdlv_current_sel].bus - 1, 0); - recalc_location_controls(hdlg, 0, 0); - ignore_change = 0; - } - break; - - case WM_COMMAND: - if (ignore_change && (LOWORD(wParam) != IDC_BUTTON_HDD_ADD) && - (LOWORD(wParam) != IDC_BUTTON_HDD_ADD_NEW) && (LOWORD(wParam) != IDC_BUTTON_HDD_REMOVE)) - return FALSE; - switch (LOWORD(wParam)) { - case IDC_COMBO_HD_BUS: - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - b = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - if (b == temp_hdd[hdlv_current_sel].bus) - goto hd_bus_skip; - hard_disk_untrack(hdlv_current_sel); - assign = (temp_hdd[hdlv_current_sel].bus == b) ? 0 : 1; - temp_hdd[hdlv_current_sel].bus = b; - recalc_location_controls(hdlg, 0, assign); - hard_disk_track(hdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); -hd_bus_skip: - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_CHANNEL: - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - hard_disk_untrack(hdlv_current_sel); - if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_MFM) - temp_hdd[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - else if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_ESDI) - temp_hdd[hdlv_current_sel].esdi_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - else if (temp_hdd[hdlv_current_sel].bus == HDD_BUS_XTA) - temp_hdd[hdlv_current_sel].xta_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - hard_disk_track(hdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_CHANNEL_IDE: - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - hard_disk_untrack(hdlv_current_sel); - temp_hdd[hdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - hard_disk_track(hdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_ID: - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - hard_disk_untrack(hdlv_current_sel); - temp_hdd[hdlv_current_sel].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); - hard_disk_track(hdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_LUN: - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - hard_disk_untrack(hdlv_current_sel); - temp_hdd[hdlv_current_sel].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - hard_disk_track(hdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_BUTTON_HDD_ADD: - hard_disk_add_open(hdlg, 1); - if (hard_disk_added) { - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - hard_disk_track_all(); - ignore_change = 0; - } - return FALSE; - - case IDC_BUTTON_HDD_ADD_NEW: - hard_disk_add_open(hdlg, 0); - if (hard_disk_added) { - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - hard_disk_track_all(); - ignore_change = 0; - } - return FALSE; - - case IDC_BUTTON_HDD_REMOVE: - memcpy(temp_hdd[hdlv_current_sel].fn, L"", 4); - hard_disk_untrack(hdlv_current_sel); - temp_hdd[hdlv_current_sel].bus = HDD_BUS_DISABLED; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ - normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - if (hd_listview_items > 0) { - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - hdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdd[0].bus - 1, 0); - } else - hdlv_current_sel = -1; - recalc_location_controls(hdlg, 0, 0); - ignore_change = 0; - return FALSE; - } - - default: - return FALSE; - } - - return FALSE; -} - - -static int -combo_id_to_string_id(int combo_id) -{ - return IDS_5376 + combo_id; -} - - -static int -combo_id_to_format_string_id(int combo_id) -{ - return IDS_5632 + combo_id; -} - - -static BOOL -win_settings_floppy_drives_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - char s[256]; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.state = 0; - - for (i = 0; i < 4; i++) { - lvI.iSubItem = 0; - if (temp_fdd_types[i] > 0) { - strcpy(s, fdd_getname(temp_fdd_types[i])); - mbstowcs(szText, s, strlen(s) + 1); - lvI.pszText = szText; - } else - lvI.pszText = plat_get_string(IDS_5376); - lvI.iItem = i; - lvI.iImage = temp_fdd_types[i]; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 2; - lvI.pszText = plat_get_string(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - - -static BOOL -win_settings_cdrom_drives_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i = 0, fsid = 0; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < 4; i++) { - fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); - - lvI.iSubItem = 0; - switch (temp_cdrom_drives[i].bus_type) { - case CDROM_BUS_DISABLED: - default: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case CDROM_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case CDROM_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - lvI.iItem = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - if (temp_cdrom_drives[i].bus_type == CDROM_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2112); - else { - wsprintf(szText, L"%ix", temp_cdrom_drives[i].speed); - lvI.pszText = szText; - } - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - - -static BOOL -win_settings_zip_drives_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i = 0, fsid = 0; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < 4; i++) { - fsid = combo_id_to_format_string_id(temp_zip_drives[i].bus_type); - - lvI.iSubItem = 0; - switch (temp_zip_drives[i].bus_type) { - case ZIP_BUS_DISABLED: - default: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case ZIP_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].ide_channel >> 1, temp_zip_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case ZIP_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id, temp_zip_drives[i].scsi_device_lun); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - lvI.iItem = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_zip_drives[i].is_250 ? IDS_5901 : IDS_5900); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - - -static BOOL -win_settings_floppy_drives_init_columns(HWND hwndList) -{ - LVCOLUMN lvc; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_2101); - - lvc.cx = 292; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - return FALSE; - - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_2059); - - lvc.cx = 50; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - return FALSE; - - lvc.iSubItem = 2; - lvc.pszText = plat_get_string(IDS_2088); - - lvc.cx = 75; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 2, &lvc) == -1) - return FALSE; - - return TRUE; -} - - -static BOOL -win_settings_cdrom_drives_init_columns(HWND hwndList) -{ - LVCOLUMN lvc; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_2082); - - lvc.cx = 342; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - return FALSE; - - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_2053); - - lvc.cx = 50; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - return FALSE; - - return TRUE; -} - - -static BOOL -win_settings_zip_drives_init_columns(HWND hwndList) -{ - LVCOLUMN lvc; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - lvc.iSubItem = 0; - lvc.pszText = plat_get_string(IDS_2082); - - lvc.cx = 342; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - return FALSE; - - lvc.iSubItem = 1; - lvc.pszText = plat_get_string(IDS_2101); - - lvc.cx = 50; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) - return FALSE; - - return TRUE; -} - - -static int -get_selected_drive(HWND hdlg, int id) -{ - int drive = -1; - int i, j = 0; - HWND h; - - for (i = 0; i < 4; i++) { - h = GetDlgItem(hdlg, id); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - drive = i; - } - - return drive; -} - - -static void -win_settings_floppy_drives_update_item(HWND hwndList, int i) -{ - LVITEM lvI; - char s[256]; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; - - if (temp_fdd_types[i] > 0) { - strcpy(s, fdd_getname(temp_fdd_types[i])); - mbstowcs(szText, s, strlen(s) + 1); - lvI.pszText = szText; - } else - lvI.pszText = plat_get_string(IDS_5376); - lvI.iImage = temp_fdd_types[i]; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - lvI.iSubItem = 2; - lvI.pszText = plat_get_string(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -} - - -static void -win_settings_cdrom_drives_update_item(HWND hwndList, int i) -{ - LVITEM lvI; - WCHAR szText[256]; - int fsid; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; - - fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); - - switch (temp_cdrom_drives[i].bus_type) { - case CDROM_BUS_DISABLED: - default: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case CDROM_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case CDROM_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - lvI.iSubItem = 1; - if (temp_cdrom_drives[i].bus_type == CDROM_BUS_DISABLED) - lvI.pszText = plat_get_string(IDS_2112); - else { - wsprintf(szText, L"%ix", temp_cdrom_drives[i].speed); - lvI.pszText = szText; - } - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -} - - -static void -win_settings_zip_drives_update_item(HWND hwndList, int i) -{ - LVITEM lvI; - WCHAR szText[256]; - int fsid; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; - - fsid = combo_id_to_format_string_id(temp_zip_drives[i].bus_type); - - switch (temp_zip_drives[i].bus_type) { - case ZIP_BUS_DISABLED: - default: - lvI.pszText = plat_get_string(fsid); - lvI.iImage = 0; - break; - case ZIP_BUS_ATAPI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].ide_channel >> 1, temp_zip_drives[i].ide_channel & 1); - lvI.pszText = szText; - lvI.iImage = 1; - break; - case ZIP_BUS_SCSI: - wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id, temp_zip_drives[i].scsi_device_lun); - lvI.pszText = szText; - lvI.iImage = 1; - break; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; - - lvI.iSubItem = 1; - lvI.pszText = plat_get_string(temp_zip_drives[i].is_250 ? IDS_5901 : IDS_5900); - lvI.iItem = i; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - return; -} - - -static void -cdrom_add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - HWND h; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - for (i = CDROM_BUS_DISABLED; i <= CDROM_BUS_SCSI; i++) { - if ((i == CDROM_BUS_DISABLED) || (i >= CDROM_BUS_ATAPI)) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(combo_id_to_string_id(i))); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_SPEED); - for (i = 1; i <= 72; i++) { - wsprintf(lptsTemp, L"%ix", i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - for (i = 0; i < 16; i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4098), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - for (i = 0; i < 8; i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4098), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - for (i = 0; i < 8; i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - free(lptsTemp); -} - - -static void cdrom_recalc_location_controls(HWND hdlg, int assign_id) -{ - int i = 0; - HWND h; - - int bus = temp_cdrom_drives[cdlv_current_sel].bus_type; - - for (i = IDT_1741; i < (IDT_1743 + 1); i++) { - h = GetDlgItem(hdlg, i); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_SPEED); - if (bus == CDROM_BUS_DISABLED) { - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } else { - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].speed - 1, 0); - } - - h = GetDlgItem(hdlg, IDT_1758); - if (bus == CDROM_BUS_DISABLED) { - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } else { - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - } - - switch(bus) { - case CDROM_BUS_ATAPI: /* ATAPI */ - h = GetDlgItem(hdlg, IDT_1743); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - if (assign_id) - temp_cdrom_drives[cdlv_current_sel].ide_channel = next_free_ide_channel(); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].ide_channel, 0); - break; - case CDROM_BUS_SCSI: /* SCSI */ - h = GetDlgItem(hdlg, IDT_1741); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDT_1742); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - if (assign_id) - next_free_scsi_id_and_lun((uint8_t *) &temp_cdrom_drives[cdlv_current_sel].scsi_device_id, (uint8_t *) &temp_cdrom_drives[cdlv_current_sel].scsi_device_lun); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_id, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_lun, 0); - break; - } -} - - -static void -zip_add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - HWND h; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_BUS); - for (i = ZIP_BUS_DISABLED; i <= ZIP_BUS_SCSI; i++) { - if ((i == ZIP_BUS_DISABLED) || (i >= ZIP_BUS_ATAPI)) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(combo_id_to_string_id(i))); - } - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_ID); - for (i = 0; i < 16; i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4098), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_LUN); - for (i = 0; i < 8; i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4098), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); - for (i = 0; i < 8; i++) { - wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - free(lptsTemp); -} - - -static void -zip_recalc_location_controls(HWND hdlg, int assign_id) -{ - int i = 0; - HWND h; - - int bus = temp_zip_drives[zdlv_current_sel].bus_type; - - for (i = IDT_1754; i < (IDT_1756 + 1); i++) { - h = GetDlgItem(hdlg, i); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_ID); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_LUN); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_CHECK250); - if (bus == ZIP_BUS_DISABLED) { - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } else { - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, BM_SETCHECK, temp_zip_drives[zdlv_current_sel].is_250, 0); - } - - switch(bus) { - case ZIP_BUS_ATAPI: /* ATAPI */ - h = GetDlgItem(hdlg, IDT_1756); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - if (assign_id) - temp_zip_drives[zdlv_current_sel].ide_channel = next_free_ide_channel(); - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_zip_drives[zdlv_current_sel].ide_channel, 0); - break; - case ZIP_BUS_SCSI: /* SCSI */ - h = GetDlgItem(hdlg, IDT_1754); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDT_1755); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - if (assign_id) - next_free_scsi_id_and_lun((uint8_t *) &temp_zip_drives[zdlv_current_sel].scsi_device_id, (uint8_t *) &temp_zip_drives[zdlv_current_sel].scsi_device_lun); - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_ID); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_zip_drives[zdlv_current_sel].scsi_device_id, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_LUN); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_zip_drives[zdlv_current_sel].scsi_device_lun, 0); - break; - } -} - - -static void -cdrom_track(uint8_t id) -{ - if (temp_cdrom_drives[id].bus_type == CDROM_BUS_ATAPI) - ide_tracking |= (2 << (temp_cdrom_drives[id].ide_channel << 3)); - else if (temp_cdrom_drives[id].bus_type == CDROM_BUS_SCSI) - scsi_tracking[temp_cdrom_drives[id].scsi_device_id] |= (1 << temp_cdrom_drives[id].scsi_device_lun); -} - - -static void -cdrom_untrack(uint8_t id) -{ - if (temp_cdrom_drives[id].bus_type == CDROM_BUS_ATAPI) - ide_tracking &= ~(2 << (temp_cdrom_drives[id].ide_channel << 3)); - else if (temp_cdrom_drives[id].bus_type == CDROM_BUS_SCSI) - scsi_tracking[temp_cdrom_drives[id].scsi_device_id] &= ~(1 << temp_cdrom_drives[id].scsi_device_lun); -} - - -static void -zip_track(uint8_t id) -{ - if (temp_zip_drives[id].bus_type == ZIP_BUS_ATAPI) - ide_tracking |= (1 << temp_zip_drives[id].ide_channel); - else if (temp_zip_drives[id].bus_type == ZIP_BUS_SCSI) - scsi_tracking[temp_zip_drives[id].scsi_device_id] |= (1 << temp_zip_drives[id].scsi_device_lun); -} - - -static void -zip_untrack(uint8_t id) -{ - if (temp_zip_drives[id].bus_type == ZIP_BUS_ATAPI) - ide_tracking &= ~(1 << temp_zip_drives[id].ide_channel); - else if (temp_zip_drives[id].bus_type == ZIP_BUS_SCSI) - scsi_tracking[temp_zip_drives[id].scsi_device_id] &= ~(1 << temp_zip_drives[id].scsi_device_lun); -} - - -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_floppy_drives_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int i = 0, old_sel = 0; - WCHAR szText[256]; - const uint8_t fd_icons[15] = { 248, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 0 }; - - switch (message) { - case WM_INITDIALOG: - fd_ignore_change = 1; - - fdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - win_settings_floppy_drives_init_columns(h); - image_list_init(h, (const uint8_t *) fd_icons); - win_settings_floppy_drives_recalc_list(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); - for (i = 0; i < 14; i++) { - if (i == 0) - SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_5376)); - else { - mbstowcs(szText, fdd_getname(i), strlen(fdd_getname(i)) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - } - } - SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); - - h = GetDlgItem(hdlg, IDC_CHECKTURBO); - SendMessage(h, BM_SETCHECK, temp_fdd_turbo[fdlv_current_sel], 0); - - h = GetDlgItem(hdlg, IDC_CHECKBPB); - SendMessage(h, BM_SETCHECK, temp_fdd_check_bpb[fdlv_current_sel], 0); - - fd_ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if (fd_ignore_change) - return FALSE; - - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_FLOPPY_DRIVES)) { - old_sel = fdlv_current_sel; - fdlv_current_sel = get_selected_drive(hdlg, IDC_LIST_FLOPPY_DRIVES); - if (fdlv_current_sel == old_sel) - return FALSE; - else if (fdlv_current_sel == -1) { - fd_ignore_change = 1; - fdlv_current_sel = old_sel; - ListView_SetItemState(h, fdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - fd_ignore_change = 0; - return FALSE; - } - fd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); - SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); - h = GetDlgItem(hdlg, IDC_CHECKTURBO); - SendMessage(h, BM_SETCHECK, temp_fdd_turbo[fdlv_current_sel], 0); - h = GetDlgItem(hdlg, IDC_CHECKBPB); - SendMessage(h, BM_SETCHECK, temp_fdd_check_bpb[fdlv_current_sel], 0); - fd_ignore_change = 0; - } - break; - - case WM_COMMAND: - if (fd_ignore_change) - return FALSE; - - fd_ignore_change = 1; - switch (LOWORD(wParam)) { - case IDC_COMBO_FD_TYPE: - h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); - temp_fdd_types[fdlv_current_sel] = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - win_settings_floppy_drives_update_item(h, fdlv_current_sel); - break; - - case IDC_CHECKTURBO: - h = GetDlgItem(hdlg, IDC_CHECKTURBO); - temp_fdd_turbo[fdlv_current_sel] = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - win_settings_floppy_drives_update_item(h, fdlv_current_sel); - break; - - case IDC_CHECKBPB: - h = GetDlgItem(hdlg, IDC_CHECKBPB); - temp_fdd_check_bpb[fdlv_current_sel] = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - win_settings_floppy_drives_update_item(h, fdlv_current_sel); - break; - } - fd_ignore_change = 0; - - default: - return FALSE; - } - - return FALSE; -} - - -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int old_sel = 0, b = 0, assign = 0; - uint32_t b2 = 0; - const uint8_t cd_icons[3] = { 249, 32, 0 }; - const uint8_t zip_icons[3] = { 250, 48, 0 }; - - switch (message) { - case WM_INITDIALOG: - rd_ignore_change = 1; - - cdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_init_columns(h); - image_list_init(h, (const uint8_t *) cd_icons); - win_settings_cdrom_drives_recalc_list(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - cdrom_add_locations(hdlg); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - - switch (temp_cdrom_drives[cdlv_current_sel].bus_type) { - case CDROM_BUS_DISABLED: - default: - b = 0; - break; - case CDROM_BUS_ATAPI: - b = 1; - break; - case CDROM_BUS_SCSI: - b = 2; - break; - } - - SendMessage(h, CB_SETCURSEL, b, 0); - - cdrom_recalc_location_controls(hdlg, 0); - - zdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - win_settings_zip_drives_init_columns(h); - image_list_init(h, (const uint8_t *) zip_icons); - win_settings_zip_drives_recalc_list(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - zip_add_locations(hdlg); - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_BUS); - - switch (temp_zip_drives[zdlv_current_sel].bus_type) { - case ZIP_BUS_DISABLED: - default: - b = 0; - break; - case ZIP_BUS_ATAPI: - b = 1; - break; - case ZIP_BUS_SCSI: - b = 2; - break; - } - - SendMessage(h, CB_SETCURSEL, b, 0); - - zip_recalc_location_controls(hdlg, 0); - - rd_ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if (rd_ignore_change) - return FALSE; - - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) { - old_sel = cdlv_current_sel; - cdlv_current_sel = get_selected_drive(hdlg, IDC_LIST_CDROM_DRIVES); - if (cdlv_current_sel == old_sel) - return FALSE; - else if (cdlv_current_sel == -1) { - rd_ignore_change = 1; - cdlv_current_sel = old_sel; - ListView_SetItemState(h, cdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - rd_ignore_change = 0; - return FALSE; - } - rd_ignore_change = 1; - - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - - switch (temp_cdrom_drives[cdlv_current_sel].bus_type) { - case CDROM_BUS_DISABLED: - default: - b = 0; - break; - case CDROM_BUS_ATAPI: - b = 1; - break; - case CDROM_BUS_SCSI: - b = 2; - break; - } - - SendMessage(h, CB_SETCURSEL, b, 0); - - cdrom_recalc_location_controls(hdlg, 0); - rd_ignore_change = 0; - } else if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_ZIP_DRIVES)) { - old_sel = zdlv_current_sel; - zdlv_current_sel = get_selected_drive(hdlg, IDC_LIST_ZIP_DRIVES); - if (zdlv_current_sel == old_sel) - return FALSE; - else if (zdlv_current_sel == -1) { - rd_ignore_change = 1; - zdlv_current_sel = old_sel; - ListView_SetItemState(h, zdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - rd_ignore_change = 0; - return FALSE; - } - rd_ignore_change = 1; - - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_BUS); - - switch (temp_zip_drives[zdlv_current_sel].bus_type) { - case ZIP_BUS_DISABLED: - default: - b = 0; - break; - case ZIP_BUS_ATAPI: - b = 1; - break; - case ZIP_BUS_SCSI: - b = 2; - break; - } - - SendMessage(h, CB_SETCURSEL, b, 0); - - zip_recalc_location_controls(hdlg, 0); - - rd_ignore_change = 0; - } - break; - - case WM_COMMAND: - if (rd_ignore_change) - return FALSE; - - rd_ignore_change = 1; - switch (LOWORD(wParam)) { - case IDC_COMBO_CD_BUS: - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - b = SendMessage(h, CB_GETCURSEL, 0, 0); - switch (b) { - case 0: - b2 = CDROM_BUS_DISABLED; - break; - case 1: - b2 = CDROM_BUS_ATAPI; - break; - case 2: - b2 = CDROM_BUS_SCSI; - break; - } - if (b2 == temp_cdrom_drives[cdlv_current_sel].bus_type) - break; - cdrom_untrack(cdlv_current_sel); - assign = (temp_cdrom_drives[cdlv_current_sel].bus_type == b2) ? 0 : 1; - if (temp_cdrom_drives[cdlv_current_sel].bus_type == CDROM_BUS_DISABLED) - temp_cdrom_drives[cdlv_current_sel].speed = 8; - temp_cdrom_drives[cdlv_current_sel].bus_type = b2; - cdrom_recalc_location_controls(hdlg, assign); - cdrom_track(cdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - break; - - case IDC_COMBO_CD_ID: - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - cdrom_untrack(cdlv_current_sel); - temp_cdrom_drives[cdlv_current_sel].scsi_device_id = SendMessage(h, CB_GETCURSEL, 0, 0); - cdrom_track(cdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - break; - - case IDC_COMBO_CD_LUN: - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - cdrom_untrack(cdlv_current_sel); - temp_cdrom_drives[cdlv_current_sel].scsi_device_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - cdrom_track(cdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - break; - - case IDC_COMBO_CD_CHANNEL_IDE: - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - cdrom_untrack(cdlv_current_sel); - temp_cdrom_drives[cdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - cdrom_track(cdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - break; - - case IDC_COMBO_CD_SPEED: - h = GetDlgItem(hdlg, IDC_COMBO_CD_SPEED); - temp_cdrom_drives[cdlv_current_sel].speed = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - break; - - case IDC_COMBO_ZIP_BUS: - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_BUS); - b = SendMessage(h, CB_GETCURSEL, 0, 0); - switch (b) { - case 0: - b2 = ZIP_BUS_DISABLED; - break; - case 1: - b2 = ZIP_BUS_ATAPI; - break; - case 2: - b2 = ZIP_BUS_SCSI; - break; - } - if (b2 == temp_zip_drives[zdlv_current_sel].bus_type) - break; - zip_untrack(zdlv_current_sel); - assign = (temp_zip_drives[zdlv_current_sel].bus_type == b2) ? 0 : 1; - temp_zip_drives[zdlv_current_sel].bus_type = b2; - zip_recalc_location_controls(hdlg, assign); - zip_track(zdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - win_settings_zip_drives_update_item(h, zdlv_current_sel); - break; - - case IDC_COMBO_ZIP_ID: - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_ID); - zip_untrack(zdlv_current_sel); - temp_zip_drives[zdlv_current_sel].scsi_device_id = SendMessage(h, CB_GETCURSEL, 0, 0); - zip_track(zdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - win_settings_zip_drives_update_item(h, zdlv_current_sel); - break; - - case IDC_COMBO_ZIP_LUN: - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_LUN); - zip_untrack(zdlv_current_sel); - temp_zip_drives[zdlv_current_sel].scsi_device_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - zip_track(zdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - win_settings_zip_drives_update_item(h, zdlv_current_sel); - break; - - case IDC_COMBO_ZIP_CHANNEL_IDE: - h = GetDlgItem(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE); - zip_untrack(zdlv_current_sel); - temp_zip_drives[zdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - zip_track(zdlv_current_sel); - h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - win_settings_zip_drives_update_item(h, zdlv_current_sel); - break; - - case IDC_CHECK250: - h = GetDlgItem(hdlg, IDC_CHECK250); - temp_zip_drives[zdlv_current_sel].is_250 = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES); - win_settings_zip_drives_update_item(h, zdlv_current_sel); - break; - } - rd_ignore_change = 0; - - default: - return FALSE; - } - - return FALSE; -} - - -void win_settings_show_child(HWND hwndParent, DWORD child_id) -{ - if (child_id == displayed_category) - return; - else - displayed_category = child_id; - - SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); - - DestroyWindow(hwndChildDialog); - - switch(child_id) { - case SETTINGS_PAGE_MACHINE: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_MACHINE, hwndParent, win_settings_machine_proc); - break; - case SETTINGS_PAGE_VIDEO: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_VIDEO, hwndParent, win_settings_video_proc); - break; - case SETTINGS_PAGE_INPUT: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_INPUT, hwndParent, win_settings_input_proc); - break; - case SETTINGS_PAGE_SOUND: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_SOUND, hwndParent, win_settings_sound_proc); - break; - case SETTINGS_PAGE_NETWORK: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_NETWORK, hwndParent, win_settings_network_proc); - break; - case SETTINGS_PAGE_PORTS: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_PORTS, hwndParent, win_settings_ports_proc); - break; - case SETTINGS_PAGE_PERIPHERALS: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); - break; - case SETTINGS_PAGE_HARD_DISKS: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); - break; - case SETTINGS_PAGE_FLOPPY_DRIVES: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_FLOPPY_DRIVES, hwndParent, win_settings_floppy_drives_proc); - break; - case SETTINGS_PAGE_OTHER_REMOVABLE_DEVICES: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_OTHER_REMOVABLE_DEVICES, hwndParent, win_settings_other_removable_devices_proc); - break; - default: - fatal("Invalid child dialog ID\n"); - return; - } - - ShowWindow(hwndChildDialog, SW_SHOWNORMAL); -} - - -static BOOL -win_settings_main_insert_categories(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < 10; i++) { - lvI.pszText = plat_get_string(IDS_2065+i); - lvI.iItem = i; - lvI.iImage = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - - -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int category, i = 0, j = 0; - const uint8_t cat_icons[11] = { 240, 241, 242, 243, 80, 244, 245, 64, 246, 247, 0 }; - - hwndParentDialog = hdlg; - - switch (message) { - case WM_INITDIALOG: - plat_pause(1); - win_settings_init(); - displayed_category = -1; - h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - image_list_init(h, (const uint8_t *) cat_icons); - win_settings_main_insert_categories(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - return TRUE; - case WM_NOTIFY: - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_SETTINGSCATLIST)) { - category = -1; - for (i = 0; i < 10; i++) { - h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - category = i; - } - if (category != -1) - win_settings_show_child(hdlg, category); - } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); - i = settings_msgbox_reset(); - if (i > 0) { - if (i == 2) - win_settings_save(); - - DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - plat_pause(0); - return TRUE; - } else - return FALSE; - case IDCANCEL: - DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - plat_pause(0); - return TRUE; - } - break; - default: - return FALSE; - } - - return FALSE; -} - - -void -win_settings_open(HWND hwnd) -{ - DialogBox(hinstance, (LPCWSTR)DLG_CONFIG, hwnd, win_settings_main_proc); -} diff --git a/backup code/win/win_stbar - Cópia.c b/backup code/win/win_stbar - Cópia.c deleted file mode 100644 index a6febd49a..000000000 --- a/backup code/win/win_stbar - Cópia.c +++ /dev/null @@ -1,1123 +0,0 @@ -/* - * 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. - * - * Implement the application's Status Bar. - * - * Version: @(#)win_stbar.c 1.0.18 2018/05/25 - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. - */ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#include -#include -#undef BITMAP -#include -#include -#include -#include -#include -#include "../86box.h" -#include "../config.h" -#include "../cpu/cpu.h" -#include "../device.h" -#include "../machine/machine.h" -#include "../disk/hdd.h" -#include "../disk/hdc.h" -#include "../disk/zip.h" -#include "../floppy/fdd.h" -#include "../scsi/scsi.h" -#include "../cdrom/cdrom.h" -#include "../cdrom/cdrom_image.h" -#include "../cdrom/cdrom_null.h" -#include "../scsi/scsi_disk.h" -#include "../network/network.h" -#include "../video/video.h" -#include "../sound/sound.h" -#include "../plat.h" -#include "../ui.h" -#include "win.h" - -#ifndef GWL_WNDPROC -#define GWL_WNDPROC GWLP_WNDPROC -#endif - - -HWND hwndSBAR; -int update_icons = 1; - - -static LONG_PTR OriginalProcedure; -static HMENU *sb_menu_handles; -static HMENU menuSBAR; -static WCHAR **sbTips; -static int *iStatusWidths; -static int *sb_part_meanings; -static int *sb_part_icons; -static int sb_parts = 0; -static int sb_ready = 0; -static uint8_t sb_map[256]; - - -/* Also used by win_settings.c */ -intptr_t -fdd_type_to_icon(int type) -{ - int ret = 512; - - switch(type) { - case 0: - break; - - case 1: case 2: case 3: case 4: - case 5: case 6: - ret = 128; - break; - - case 7: case 8: case 9: case 10: - case 11: case 12: case 13: - ret = 144; - break; - - default: - break; - } - - return(ret); -} - - -/* FIXME: should be hdd_count() in hdd.c */ -static int -hdd_count(int bus) -{ - int c = 0; - int i; - - for (i=0; i= SB_TEXT) || !sb_ready) - return; - - found = sb_map[tag]; - if (found != 0xff) { - sb_part_icons[found] &= ~1; - sb_part_icons[found] |= active; - - SendMessage(hwndSBAR, SB_SETICON, found, - (LPARAM)hIcon[sb_part_icons[found]]); - } -} - - -/* API: This is for the drive state indicator. */ -void -ui_sb_update_icon_state(int tag, int state) -{ - uint8_t found = 0xff; - - if (((tag & 0xf0) >= SB_HDD) || !sb_ready) - return; - - found = sb_map[tag]; - if (found != 0xff) { - sb_part_icons[found] &= ~256; - sb_part_icons[found] |= (state ? 256 : 0); - - SendMessage(hwndSBAR, SB_SETICON, found, - (LPARAM)hIcon[sb_part_icons[found]]); - } -} - - -static void -StatusBarCreateFloppyTip(int part) -{ - WCHAR wtext[512]; - WCHAR tempTip[512]; - - int drive = sb_part_meanings[part] & 0xf; - - mbstowcs(wtext, fdd_getname(fdd_get_type(drive)), - strlen(fdd_getname(fdd_get_type(drive))) + 1); - if (wcslen(floppyfns[drive]) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2117), - drive+1, wtext, plat_get_string(IDS_2057)); - } else { - _swprintf(tempTip, plat_get_string(IDS_2117), - drive+1, wtext, floppyfns[drive]); - } - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *)malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - - -static void -StatusBarCreateCdromTip(int part) -{ - WCHAR tempTip[512]; - WCHAR *szText; - int id; - int drive = sb_part_meanings[part] & 0xf; - int bus = cdrom_drives[drive].bus_type; - - id = IDS_5377 + (bus - 1); - szText = plat_get_string(id); - - if (cdrom_drives[drive].host_drive == 200) { - if (wcslen(cdrom_image[drive].image_path) == 0) - _swprintf(tempTip, plat_get_string(IDS_5120), drive+1, szText, plat_get_string(IDS_2057)); - else - _swprintf(tempTip, plat_get_string(IDS_5120), drive+1, szText, cdrom_image[drive].image_path); - } else - _swprintf(tempTip, plat_get_string(IDS_5120), drive+1, szText, plat_get_string(IDS_2057)); - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *)malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - - -static void -StatusBarCreateZIPTip(int part) -{ - WCHAR tempTip[512]; - WCHAR *szText; - int id; - int drive = sb_part_meanings[part] & 0xf; - int bus = zip_drives[drive].bus_type; - - id = IDS_5377 + (bus - 1); - szText = plat_get_string(id); - - int type = zip_drives[drive].is_250 ? 250 : 100; - - if (wcslen(zip_drives[drive].image_path) == 0) { - _swprintf(tempTip, plat_get_string(IDS_2054), - type, drive+1, szText, plat_get_string(IDS_2057)); - } else { - _swprintf(tempTip, plat_get_string(IDS_2054), - type, drive+1, szText, zip_drives[drive].image_path); - } - - if (sbTips[part] != NULL) { - free(sbTips[part]); - sbTips[part] = NULL; - } - sbTips[part] = (WCHAR *)malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - - -static void -StatusBarCreateDiskTip(int part) -{ - WCHAR tempTip[512]; - WCHAR *szText; - int id; - int bus = sb_part_meanings[part] & 0xf; - - id = IDS_4352 + (bus - 1); - szText = plat_get_string(id); - - _swprintf(tempTip, plat_get_string(IDS_4096), szText); - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *)malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - - -static void -StatusBarCreateNetworkTip(int part) -{ - WCHAR tempTip[512]; - - _swprintf(tempTip, plat_get_string(IDS_2069)); - - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *)malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - - -static void -StatusBarCreateSoundTip(int part) -{ - WCHAR tempTip[512]; - - _swprintf(tempTip, plat_get_string(IDS_2068)); - - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *)malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - - -/* API */ -void -ui_sb_update_tip(int meaning) -{ - uint8_t part = 0xff; - - if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) return; - - part = sb_map[meaning]; - - if (part != 0xff) { - switch(meaning & 0xf0) { - case SB_FLOPPY: - StatusBarCreateFloppyTip(part); - break; - - case SB_CDROM: - StatusBarCreateCdromTip(part); - break; - - case SB_ZIP: - StatusBarCreateZIPTip(part); - break; - - case SB_HDD: - StatusBarCreateDiskTip(part); - break; - - case SB_NETWORK: - StatusBarCreateNetworkTip(part); - break; - - case SB_SOUND: - StatusBarCreateSoundTip(part); - break; - - default: - break; - } - - SendMessage(hwndSBAR, SB_SETTIPTEXT, part, (LPARAM)sbTips[part]); - } -} - - -static void -StatusBarDestroyMenus(void) -{ - int i; - - if (sb_parts == 0) return; - - if (! sb_menu_handles) return; - - for (i=0; i 0) { - for (i = 0; i < sb_parts; i++) - SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM)NULL); - SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM)0, (LPARAM)NULL); - - if (iStatusWidths) { - free(iStatusWidths); - iStatusWidths = NULL; - } - if (sb_part_meanings) { - free(sb_part_meanings); - sb_part_meanings = NULL; - } - if (sb_part_icons) { - free(sb_part_icons); - sb_part_icons = NULL; - } - StatusBarDestroyMenus(); - StatusBarDestroyTips(); - } - - memset(sb_map, 0xff, sizeof(sb_map)); - - sb_parts = 0; - for (i=0; i= (sb_parts - 1)) return; - - pt.x = id * SB_ICON_WIDTH; /* Justify to the left. */ - pt.y = 0; /* Justify to the top. */ - ClientToScreen(hwnd, (LPPOINT) &pt); - TrackPopupMenu(sb_menu_handles[id], - TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, - pt.x, pt.y, 0, hwndSBAR, NULL); -} - - -void -ui_sb_mount_floppy_img(uint8_t id, int part, uint8_t wp, wchar_t *file_name) -{ - fdd_close(id); - ui_writeprot[id] = wp; - fdd_load(id, file_name); - ui_sb_update_icon_state(SB_FLOPPY | id, wcslen(floppyfns[id]) ? 0 : 1); - EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | (wcslen(floppyfns[id]) ? MF_ENABLED : MF_GRAYED)); - EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EXPORT_TO_86F | id, MF_BYCOMMAND | (wcslen(floppyfns[id]) ? MF_ENABLED : MF_GRAYED)); - ui_sb_update_tip(SB_FLOPPY | id); - config_save(); -} - - -void -ui_sb_mount_zip_img(uint8_t id, int part, uint8_t wp, wchar_t *file_name) -{ - zip_close(id); - zip_drives[id].ui_writeprot = wp; - zip_load(id, file_name); - zip_insert(id); - ui_sb_update_icon_state(SB_ZIP | id, wcslen(zip_drives[id].image_path) ? 0 : 1); - EnableMenuItem(sb_menu_handles[part], IDM_ZIP_EJECT | id, MF_BYCOMMAND | (wcslen(zip_drives[id].image_path) ? MF_ENABLED : MF_GRAYED)); - EnableMenuItem(sb_menu_handles[part], IDM_ZIP_RELOAD | id, MF_BYCOMMAND | (wcslen(zip_drives[id].image_path) ? MF_GRAYED : MF_ENABLED)); - ui_sb_update_tip(SB_ZIP | id); - config_save(); -} - - -/* Handle messages for the Status Bar window. */ -#ifdef __amd64__ -static LRESULT CALLBACK -#else -static BOOL CALLBACK -#endif -StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - WCHAR temp_path[1024]; - RECT rc; - POINT pt; - int ret = 0; - int item_id = 0; - int item_params = 0; - int id = 0; - uint8_t part = 0; - - switch (message) { - case WM_COMMAND: - item_id = LOWORD(wParam) & 0xff00; /* low 8 bits */ - item_params = LOWORD(wParam) & 0x00ff; /* high 8 bits */ - - switch (item_id) { - case IDM_FLOPPY_IMAGE_NEW: - id = item_params & 0x0003; - part = sb_map[SB_FLOPPY | id]; - NewFloppyDialogCreate(hwnd, id, part); - break; - - case IDM_FLOPPY_IMAGE_EXISTING: - case IDM_FLOPPY_IMAGE_EXISTING_WP: - id = item_params & 0x0003; - part = sb_map[SB_FLOPPY | id]; - if ((part == 0xff) || (sb_menu_handles == NULL)) - break; - - ret = file_dlg_w_st(hwnd, IDS_2118, floppyfns[id], 0); - if (! ret) - ui_sb_mount_floppy_img(id, part, (item_id == IDM_FLOPPY_IMAGE_EXISTING_WP) ? 1 : 0, wopenfilestring); - break; - - case IDM_FLOPPY_EJECT: - id = item_params & 0x0003; - part = sb_map[SB_FLOPPY | id]; - if ((part == 0xff) || (sb_menu_handles == NULL)) - break; - - fdd_close(id); - ui_sb_update_icon_state(SB_FLOPPY | id, 1); - EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EXPORT_TO_86F | id, MF_BYCOMMAND | MF_GRAYED); - ui_sb_update_tip(SB_FLOPPY | id); - config_save(); - break; - - case IDM_FLOPPY_EXPORT_TO_86F: - id = item_params & 0x0003; - part = sb_map[SB_FLOPPY | id]; - if ((part == 0xff) || (sb_menu_handles == NULL)) - break; - - ret = file_dlg_w_st(hwnd, IDS_2076, floppyfns[id], 1); - if (! ret) { - plat_pause(1); - ret = d86f_export(id, wopenfilestring); - if (!ret) - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4108); - plat_pause(0); - } - break; - - case IDM_CDROM_MUTE: - id = item_params & 0x0007; - part = sb_map[SB_CDROM | id]; - if ((part == 0xff) || (sb_menu_handles == NULL)) - break; - - cdrom_drives[id].sound_on ^= 1; - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_MUTE | id, cdrom_drives[id].sound_on ? MF_UNCHECKED : MF_CHECKED); - config_save(); - sound_cd_thread_reset(); - break; - - case IDM_CDROM_EMPTY: - id = item_params & 0x0007; - cdrom_eject(id); - break; - - case IDM_CDROM_RELOAD: - id = item_params & 0x0007; - cdrom_reload(id); - break; - - case IDM_CDROM_IMAGE: - id = item_params & 0x0007; - part = sb_map[SB_CDROM | id]; - if ((part == 0xff) || (sb_menu_handles == NULL)) - break; - - if (!file_dlg_w_st(hwnd, IDS_2075, cdrom_image[id].image_path, 0)) { - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - wcscpy(temp_path, wopenfilestring); - if (!cdrom_image[id].prev_image_path) - cdrom_image[id].prev_image_path = (wchar_t *) malloc(1024); - wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path); - cdrom[id]->handler->exit(id); - cdrom_close_handler(id); - memset(cdrom_image[id].image_path, 0, 2048); - image_open(id, temp_path); - /* Signal media change to the emulated machine. */ - cdrom_insert(cdrom[id]); - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); - cdrom_drives[id].host_drive = (wcslen(cdrom_image[id].image_path) == 0) ? 0 : 200; - if (cdrom_drives[id].host_drive == 200) { - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED); - ui_sb_update_icon_state(SB_CDROM | id, 0); - } else { - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); - ui_sb_update_icon_state(SB_CDROM | id, 1); - } - EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - ui_sb_update_tip(SB_CDROM | id); - config_save(); - } - break; - - case IDM_ZIP_IMAGE_NEW: - id = item_params & 0x0003; - part = sb_map[SB_ZIP | id]; - NewFloppyDialogCreate(hwnd, id | 0x80, part); /* NewZIPDialogCreate */ - break; - - case IDM_ZIP_IMAGE_EXISTING: - case IDM_ZIP_IMAGE_EXISTING_WP: - id = item_params & 0x0003; - part = sb_map[SB_ZIP | id]; - if ((part == 0xff) || (sb_menu_handles == NULL)) - break; - - ret = file_dlg_w_st(hwnd, IDS_2058, zip_drives[id].image_path, 0); - if (! ret) - ui_sb_mount_zip_img(id, part, (item_id == IDM_ZIP_IMAGE_EXISTING_WP) ? 1 : 0, wopenfilestring); - break; - - case IDM_ZIP_EJECT: - id = item_params & 0x0003; - zip_eject(id); - break; - - case IDM_ZIP_RELOAD: - id = item_params & 0x0003; - zip_reload(id); - break; - - default: - break; - } - return(0); - - case WM_LBUTTONDOWN: - case WM_RBUTTONDOWN: - GetClientRect(hwnd, (LPRECT)& rc); - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - if (PtInRect((LPRECT) &rc, pt)) - StatusBarPopupMenu(hwnd, pt, (pt.x / SB_ICON_WIDTH)); - break; - - case WM_LBUTTONDBLCLK: - GetClientRect(hwnd, (LPRECT)& rc); - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - item_id = (pt.x / SB_ICON_WIDTH); - if (PtInRect((LPRECT) &rc, pt) && (item_id < sb_parts)) { - if (sb_part_meanings[item_id] == SB_SOUND) - SoundGainDialogCreate(hwndMain); - } - break; - - default: - return(CallWindowProc((WNDPROC)OriginalProcedure, - hwnd, message, wParam, lParam)); - } - - return(0); -} - - -/* API: Create and set up the Status Bar window. */ -void -StatusBarCreate(HWND hwndParent, uintptr_t idStatus, HINSTANCE hInst) -{ - RECT rectDialog; - int dw, dh; - uintptr_t i; - - /* Load our icons into the cache for faster access. */ - for (i = 128; i < 130; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 144; i < 146; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 160; i < 162; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 176; i < 178; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 192; i < 194; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 208; i < 210; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 259; i < 260; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 384; i < 386; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 400; i < 402; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 416; i < 418; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 432; i < 434; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - - GetWindowRect(hwndParent, &rectDialog); - dw = rectDialog.right - rectDialog.left; - dh = rectDialog.bottom - rectDialog.top; - - /* Load the Common Controls DLL if needed. */ - InitCommonControls(); - - /* Create the window, and make sure it's using the STATUS class. */ - hwndSBAR = CreateWindowEx(0, - STATUSCLASSNAME, - (LPCTSTR)NULL, - SBARS_SIZEGRIP|WS_CHILD|WS_VISIBLE|SBT_TOOLTIPS, - 0, dh-17, dw, 17, - hwndParent, - (HMENU)idStatus, hInst, NULL); - - /* Replace the original procedure with ours. */ - OriginalProcedure = GetWindowLongPtr(hwndSBAR, GWLP_WNDPROC); - SetWindowLongPtr(hwndSBAR, GWL_WNDPROC, (LONG_PTR)&StatusBarProcedure); - - SendMessage(hwndSBAR, SB_SETMINHEIGHT, (WPARAM)17, (LPARAM)0); - - /* Align the window with the parent (main) window. */ - GetWindowRect(hwndSBAR, &rectDialog); - SetWindowPos(hwndSBAR, - HWND_TOPMOST, - rectDialog.left, rectDialog.top, - rectDialog.right-rectDialog.left, - rectDialog.bottom-rectDialog.top, - SWP_SHOWWINDOW); - - /* Load the dummu menu for this window. */ - menuSBAR = LoadMenu(hInst, SB_MENU_NAME); - - /* Initialize the status bar. This is clumsy. */ - sb_parts = 1; - iStatusWidths = (int *)malloc(sb_parts * sizeof(int)); - memset(iStatusWidths, 0, sb_parts * sizeof(int)); - sb_part_meanings = (int *)malloc(sb_parts * sizeof(int)); - memset(sb_part_meanings, 0, sb_parts * sizeof(int)); - sb_part_icons = (int *)malloc(sb_parts * sizeof(int)); - memset(sb_part_icons, 0, sb_parts * sizeof(int)); - sb_menu_handles = (HMENU *)malloc(sb_parts * sizeof(HMENU)); - memset(sb_menu_handles, 0, sb_parts * sizeof(HMENU)); - sbTips = (WCHAR **)malloc(sb_parts * sizeof(WCHAR *)); - memset(sbTips, 0, sb_parts * sizeof(WCHAR *)); - sb_parts = 0; - iStatusWidths[sb_parts] = -1; - sb_part_meanings[sb_parts] = SB_TEXT; - sb_part_icons[sb_parts] = -1; - sb_parts++; - SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM)sb_parts, (LPARAM)iStatusWidths); - SendMessage(hwndSBAR, SB_SETTEXT, 0 | SBT_NOBORDERS, - (LPARAM)L"Welcome to 86Box !"); - sb_ready = 1; -} - - -/* API (Settings) */ -void -ui_sb_check_menu_item(int tag, int id, int chk) -{ - uint8_t part; - - part = sb_map[tag]; - if ((part == 0xff) || (sb_menu_handles == NULL)) - return; - - CheckMenuItem(sb_menu_handles[part], id, chk); -} - - -/* API (Settings) */ -void -ui_sb_enable_menu_item(int tag, int id, int flg) -{ - uint8_t part; - - part = sb_map[tag]; - if ((part == 0xff) || (sb_menu_handles == NULL)) - return; - - EnableMenuItem(sb_menu_handles[part], id, flg); -} - - -/* API */ -void -ui_sb_set_text_w(wchar_t *wstr) -{ - uint8_t part = 0xff; - - if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) - return; - - part = sb_map[SB_TEXT]; - - if (part != 0xff) - SendMessage(hwndSBAR, SB_SETTEXT, part | SBT_NOBORDERS, (LPARAM)wstr); -} - - -/* API */ -void -ui_sb_set_text(char *str) -{ - static wchar_t wstr[512]; - - memset(wstr, 0x00, sizeof(wstr)); - mbstowcs(wstr, str, strlen(str) + 1); - ui_sb_set_text_w(wstr); -} - - -/* API */ -void -ui_sb_bugui(char *str) -{ - static wchar_t wstr[512]; - - memset(wstr, 0x00, sizeof(wstr)); - mbstowcs(wstr, str, strlen(str) + 1); - ui_sb_set_text_w(wstr); -}