diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 724e1fda6..ec3b2c628 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -103,8 +103,29 @@ if(INSTRUMENT) add_compile_definitions(USE_INSTRUMENT) endif() -target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom rdisk mo hdd - net print scsi sio snd utils vid voodoo plat ui) +target_link_libraries(86Box + cpu + chipset + mch + dev + mem + fdd + game + cdrom + rdisk + mo + hdd + net + print + scsi + sio + snd + utils + vid + voodoo + plat + ui +) if(HAIKU) target_link_libraries(86Box be) diff --git a/src/device/cartridge.c b/src/device/cartridge.c index 00464026a..cb3c5e412 100644 --- a/src/device/cartridge.c +++ b/src/device/cartridge.c @@ -92,8 +92,8 @@ cart_image_close(int drive) static void cart_image_load(int drive, char *fn) { - FILE *fp; - uint32_t size; + FILE *fp = NULL; + uint32_t size = 0; uint32_t base = 0x00000000; cart_image_close(drive); @@ -137,7 +137,7 @@ cart_image_load(int drive, char *fn) static void cart_load_common(int drive, char *fn, uint8_t hard_reset) { - FILE *fp; + FILE *fp = NULL; cartridge_log("Cartridge: loading drive %d with '%s'\n", drive, fn); diff --git a/src/disk/mo.c b/src/disk/mo.c index b287f68a0..5ffe74f78 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -664,8 +664,17 @@ static void mo_buf_alloc(mo_t *dev, uint32_t len) { mo_log(dev->log, "Allocated buffer length: %i\n", len); - if (dev->buffer == NULL) + + if (dev->buffer == NULL) { dev->buffer = (uint8_t *) malloc(len); + dev->buffer_sz = len; + } + + if (len > dev->buffer_sz) { + uint8_t *buf = (uint8_t *) realloc(dev->buffer, len); + dev->buffer = buf; + dev->buffer_sz = len; + } } static void diff --git a/src/disk/rdisk.c b/src/disk/rdisk.c index b51dc4e66..683b1e963 100644 --- a/src/disk/rdisk.c +++ b/src/disk/rdisk.c @@ -747,8 +747,17 @@ static void rdisk_buf_alloc(rdisk_t *dev, const uint32_t len) { rdisk_log(dev->log, "Allocated buffer length: %i\n", len); - if (dev->buffer == NULL) + + if (dev->buffer == NULL) { dev->buffer = (uint8_t *) malloc(len); + dev->buffer_sz = len; + } + + if (len > dev->buffer_sz) { + uint8_t *buf = (uint8_t *) realloc(dev->buffer, len); + dev->buffer = buf; + dev->buffer_sz = len; + } } static void diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 8bc946388..bc81c8662 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -105,39 +105,39 @@ static const struct void (*close)(int drive); int size; } loaders[] = { - { "001", img_load, img_close, -1}, - { "002", img_load, img_close, -1}, - { "003", img_load, img_close, -1}, - { "004", img_load, img_close, -1}, - { "005", img_load, img_close, -1}, - { "006", img_load, img_close, -1}, - { "007", img_load, img_close, -1}, - { "008", img_load, img_close, -1}, - { "009", img_load, img_close, -1}, - { "010", img_load, img_close, -1}, - { "12", img_load, img_close, -1}, - { "144", img_load, img_close, -1}, - { "360", img_load, img_close, -1}, - { "720", img_load, img_close, -1}, - { "86F", d86f_load, d86f_close, -1}, - { "BIN", img_load, img_close, -1}, - { "CQ", img_load, img_close, -1}, - { "CQM", img_load, img_close, -1}, - { "DDI", img_load, img_close, -1}, - { "DSK", img_load, img_close, -1}, - { "FDI", fdi_load, fdi_close, -1}, - { "FDF", img_load, img_close, -1}, - { "FLP", img_load, img_close, -1}, - { "HDM", img_load, img_close, -1}, - { "IMA", img_load, img_close, -1}, - { "IMD", imd_load, imd_close, -1}, - { "IMG", img_load, img_close, -1}, - { "JSON", pcjs_load, pcjs_close, -1}, - { "MFM", mfm_load, mfm_close, -1}, - { "TD0", td0_load, td0_close, -1}, - { "VFD", img_load, img_close, -1}, - { "XDF", img_load, img_close, -1}, - { 0, 0, 0, 0 } + { "001", img_load, img_close, -1 }, + { "002", img_load, img_close, -1 }, + { "003", img_load, img_close, -1 }, + { "004", img_load, img_close, -1 }, + { "005", img_load, img_close, -1 }, + { "006", img_load, img_close, -1 }, + { "007", img_load, img_close, -1 }, + { "008", img_load, img_close, -1 }, + { "009", img_load, img_close, -1 }, + { "010", img_load, img_close, -1 }, + { "12", img_load, img_close, -1 }, + { "144", img_load, img_close, -1 }, + { "360", img_load, img_close, -1 }, + { "720", img_load, img_close, -1 }, + { "86F", d86f_load, d86f_close, -1 }, + { "BIN", img_load, img_close, -1 }, + { "CQ", img_load, img_close, -1 }, + { "CQM", img_load, img_close, -1 }, + { "DDI", img_load, img_close, -1 }, + { "DSK", img_load, img_close, -1 }, + { "FDI", fdi_load, fdi_close, -1 }, + { "FDF", img_load, img_close, -1 }, + { "FLP", img_load, img_close, -1 }, + { "HDM", img_load, img_close, -1 }, + { "IMA", img_load, img_close, -1 }, + { "IMD", imd_load, imd_close, -1 }, + { "IMG", img_load, img_close, -1 }, + { "JSON", pcjs_load, pcjs_close, -1 }, + { "MFM", mfm_load, mfm_close, -1 }, + { "TD0", td0_load, td0_close, -1 }, + { "VFD", img_load, img_close, -1 }, + { "XDF", img_load, img_close, -1 }, + { 0, 0, 0, 0 } }; static const struct { @@ -211,7 +211,7 @@ fdd_get_internal_name(int type) int fdd_get_from_internal_name(char *s) { - int c = 0; + int c = 0; while (strlen(drive_types[c].internal_name)) { if (!strcmp((char *) drive_types[c].internal_name, s)) @@ -466,7 +466,7 @@ fdd_load(int drive, char *fn) if (!fn) return; if (strstr(fn, "wp://") == fn) { - offs = 5; + offs = 5; ui_writeprot[drive] = 1; } fn += offs; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 7ab675a6c..6de1586dc 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -498,6 +498,7 @@ extern int machine_at_cmdpc_init(const machine_t *); extern int machine_at_portableii_init(const machine_t *); extern int machine_at_portableiii_init(const machine_t *); extern int machine_at_grid1520_init(const machine_t *); +extern int machine_at_mpfpc900_init(const machine_t *); extern int machine_at_mr286_init(const machine_t *); extern int machine_at_pc8_init(const machine_t *); extern int machine_at_m290_init(const machine_t *); @@ -1319,7 +1320,11 @@ extern const device_t jukopc_device; extern int machine_xt_jukopc_init(const machine_t *); extern int machine_xt_kaypropc_init(const machine_t *); extern int machine_xt_micoms_xl7turbo_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t pc500_device; +#endif extern int machine_xt_pc500_init(const machine_t *); +extern int machine_xt_pc500plus_init(const machine_t *); extern int machine_xt_pc700_init(const machine_t *); extern int machine_xt_pc4i_init(const machine_t *); extern int machine_xt_openxt_init(const machine_t *); diff --git a/src/include/86box/mo.h b/src/include/86box/mo.h index 6d308adb8..76e7cbdbe 100644 --- a/src/include/86box/mo.h +++ b/src/include/86box/mo.h @@ -140,6 +140,7 @@ typedef struct mo_t { void * log; uint8_t *buffer; + size_t buffer_sz; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; diff --git a/src/include/86box/path.h b/src/include/86box/path.h index f1c5e4177..ef66c0a30 100644 --- a/src/include/86box/path.h +++ b/src/include/86box/path.h @@ -1,3 +1,4 @@ +extern char *path_get_basename(const char *path); extern void path_get_dirname(char *dest, const char *path); extern char *path_get_filename(char *s); extern char *path_get_extension(char *s); @@ -5,4 +6,4 @@ extern void path_append_filename(char *dest, const char *s1, const char *s2); extern void path_slash(char *path); extern const char *path_get_slash(char *path); extern void path_normalize(char *path); -extern int path_abs(char *path); \ No newline at end of file +extern int path_abs(char *path); diff --git a/src/include/86box/rdisk.h b/src/include/86box/rdisk.h index df48ba703..c226a2c9d 100644 --- a/src/include/86box/rdisk.h +++ b/src/include/86box/rdisk.h @@ -117,6 +117,7 @@ typedef struct rdisk_t { void *log; uint8_t *buffer; + size_t buffer_sz; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; diff --git a/src/include/86box/scsi_cdrom.h b/src/include/86box/scsi_cdrom.h index c01f347a8..005223e27 100644 --- a/src/include/86box/scsi_cdrom.h +++ b/src/include/86box/scsi_cdrom.h @@ -36,6 +36,7 @@ typedef struct scsi_cdrom_t { void * log; uint8_t * buffer; + size_t buffer_sz; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 289201b04..d5d620670 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -388,6 +388,7 @@ typedef struct scsi_common_s { void * log; uint8_t * temp_buffer; + size_t temp_buffer_sz; /* This is atapi_cdb in ATAPI-supporting devices, and pad in SCSI-only devices. diff --git a/src/include/86box/snd_emu8k.h b/src/include/86box/snd_emu8k.h index 4bad23b97..fcbad4cfa 100644 --- a/src/include/86box/snd_emu8k.h +++ b/src/include/86box/snd_emu8k.h @@ -199,8 +199,8 @@ typedef struct emu8k_voice_t { * something, similarly to targets and current, but... of what? * what is curious is that if they are already zero, they are not written to, so it really * looks like they are information about the status of the channel. (lfo position maybe?) */ - uint32_t unknown_data0_4; - uint32_t unknown_data0_5; + uint32_t z2; + uint32_t z1; union { uint32_t psst; struct { @@ -229,7 +229,7 @@ typedef struct emu8k_voice_t { }; #define CCCA_FILTQ_GET(ccca) (ccca >> 28) #define CCCA_FILTQ_SET(ccca, q) ccca = (ccca & 0x0FFFFFFF) | (q << 28) -/* Bit 27 should always be zero */ +/* Bit 27 should always be zero on EMU8000 */ #define CCCA_DMA_ACTIVE(ccca) (ccca & 0x04000000) #define CCCA_DMA_WRITE_MODE(ccca) (ccca & 0x02000000) #define CCCA_DMA_WRITE_RIGHT(ccca) (ccca & 0x01000000) @@ -316,7 +316,9 @@ typedef struct emu8k_voice_t { int env_engine_on; - emu8k_mem_internal_t addr, loop_start, loop_end; + emu8k_mem_internal_t addr; + emu8k_mem_internal_t loop_start; + emu8k_mem_internal_t loop_end; int32_t initial_att; int32_t initial_filter; diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index b588a3daf..cbd6c511a 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -141,6 +141,7 @@ typedef struct svga_t { int render_line_offset; int start_retrace_latch; int vga_mode; + int half_pixel; /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : 0MB-1MB - VRAM @@ -449,6 +450,7 @@ extern void ibm_rgb528_ramdac_set_ref_clock(void *priv, svga_t *svga, float r extern void icd2061_write(void *priv, int val); extern float icd2061_getclock(int clock, void *priv); +extern void icd2061_set_ref_clock(void *priv, svga_t *svga, float ref_clock); /* The code is the same, the #define's are so that the correct name can be used. */ # define ics9161_write icd2061_write @@ -465,6 +467,8 @@ extern uint8_t sc1148x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svg extern void sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga); extern uint8_t sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga); +extern void sc1502x_rs2_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); +extern uint8_t sc1502x_rs2_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); extern void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); extern uint8_t sdac_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); @@ -516,6 +520,7 @@ extern const device_t sc11487_ramdac_device; extern const device_t sc11486_ramdac_device; extern const device_t sc11484_nors2_ramdac_device; extern const device_t sc1502x_ramdac_device; +extern const device_t sc1502x_rs2_ramdac_device; extern const device_t sdac_ramdac_device; extern const device_t stg_ramdac_device; extern const device_t tkd8001_ramdac_device; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 89e234265..c87ef4f77 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -412,7 +412,7 @@ extern const device_t cga_pravetz_device; /* Compaq CGA */ extern const device_t compaq_cga_device; extern const device_t compaq_cga_2_device; -extern const device_t compaq_plasma_device; +extern const device_t compaq_plasma_device; /* Olivetti OGC */ extern const device_t ogc_device; @@ -513,8 +513,11 @@ extern const device_t realtek_rtg3106_device; extern const device_t s3_orchid_86c911_isa_device; extern const device_t s3_diamond_stealth_vram_isa_device; extern const device_t s3_ami_86c924_isa_device; +extern const device_t s3_elsa_winner1000_86c928_vlb_device; +extern const device_t s3_elsa_winner2000_86c928_isa_device; extern const device_t s3_metheus_86c928_isa_device; extern const device_t s3_metheus_86c928_vlb_device; +extern const device_t s3_elsa_winner1000_86c928_pci_device; extern const device_t s3_spea_mercury_lite_86c928_pci_device; extern const device_t s3_spea_mirage_86c801_isa_device; extern const device_t s3_winner1000_805_isa_device; @@ -642,9 +645,9 @@ extern const device_t wy700_device; extern const device_t v6355d_device; /* Tandy */ -extern const device_t tandy_1000_video_device; -extern const device_t tandy_1000hx_video_device; -extern const device_t tandy_1000sl_video_device; +extern const device_t tandy_1000_video_device; +extern const device_t tandy_1000hx_video_device; +extern const device_t tandy_1000sl_video_device; #endif diff --git a/src/machine/m_at_286.c b/src/machine/m_at_286.c index f74ad5115..a1b71a817 100644 --- a/src/machine/m_at_286.c +++ b/src/machine/m_at_286.c @@ -328,6 +328,27 @@ machine_at_grid1520_init(const machine_t *model) { return ret; } +int +machine_at_mpfpc900_init(const machine_t *model) { + int ret = 0; + + ret = bios_load_linear("roms/machines/pc900/mpf_pc900_v207a.bin", + 0x000f8000, 32768, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params); + + mem_remap_top(384); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + int machine_at_mr286_init(const machine_t *model) { diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index b0651a8af..6101513cd 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -155,6 +155,10 @@ static const device_config_t cu430hx_config[] = { .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1003DK08.BIO", "roms/machines/cu430hx/1003DK08.BI1", "roms/machines/cu430hx/1003DK08.BI2", "roms/machines/cu430hx/1003DK08.BI3", "roms/machines/cu430hx/1003DK08.RCV", "" } }, + { .name = "Intel AMIBIOS - Revision 1.00.04.DK0K (NEC PowerMate V2xxx/P2xxx)", .internal_name = "powermatev2p2", .bios_type = BIOS_NORMAL, + .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1004DK0K.BIO", "roms/machines/cu430hx/1004DK0K.BI1", + "roms/machines/cu430hx/1004DK0K.BI2", "roms/machines/cu430hx/1004DK0K.BI3", + "roms/machines/cu430hx/1004DK0K.RCV", "" } }, { .name = "Intel AMIBIOS - Revision 1.00.06.DK0", .internal_name = "cu430hx", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1006DK0_.BIO", "roms/machines/cu430hx/1006DK0_.BI1", "roms/machines/cu430hx/1006DK0_.BI2", "roms/machines/cu430hx/1006DK0_.BI3", diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index b7d840224..9dba8795f 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -774,14 +774,14 @@ pit_irq0_timer_pcjr(int new_out, int old_out, UNUSED(void *priv)) static const device_config_t pcjr_config[] = { // clang-format off { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = PCJR_RGB, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = PCJR_RGB, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "RGB", .value = PCJR_RGB }, { .description = "Composite", .value = PCJR_COMPOSITE }, { .description = "RGB (no brown)", .value = PCJR_RGB_NO_BROWN }, @@ -807,11 +807,11 @@ static const device_config_t pcjr_config[] = { .bios = { { 0 } } }, { - .name = "apply_hd", - .description = "Apply overscan deltas", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "apply_hd", + .description = "Apply overscan deltas", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 954483d62..815045389 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -974,13 +974,88 @@ machine_xt_micoms_xl7turbo_init(const machine_t *model) return ret; } +static const device_config_t pc500_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "pc500_330", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "3.30", + .internal_name = "pc500_330", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { "roms/machines/pc500/rom330.bin", "" } + }, + { + .name = "3.10", + .internal_name = "pc500_310", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { "roms/machines/pc500/rom310.bin", "" } + }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t pc500_device = { + .name = "Multitech PC-500", + .internal_name = "pc500_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = pc500_config +}; + int machine_xt_pc500_init(const machine_t *model) +{ + int ret = 0; + const char *fn; + + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000fe000, 8192, 0); + device_context_restore(); + + if (bios_only || !ret) + return ret; + + device_add(&kbc_pc_device); + + machine_xt_common_init(model, 0); + + return ret; +} + +int +machine_xt_pc500plus_init(const machine_t *model) { int ret; ret = bios_load_linear("roms/machines/pc500/rom404.bin", - 0x000f8000, 32768, 0); + 0x000fc000, 16384, 0); if (bios_only || !ret) return ret; diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 079cd4555..13d98e6f9 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -2426,7 +2426,7 @@ machine_xt_m19_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/m19/BIOS.BIN", + ret = bios_load_linear("roms/machines/m19/Olivetti M19 Resident Diagnostics Rev 3.71.BIN", 0x000fc000, 16384, 0); ret &= rom_present("roms/machines/m19/MBM2764-30 8514 107 AB PCF3.BIN"); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 7891bb3db..20baadfcf 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1129,6 +1129,49 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, + .device = &pc500_device, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Multitech PC-500 plus", + .internal_name = "pc500plus", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_pc500plus_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_pc_device, + .kbc_params = 0x00000000, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, .device = NULL, .kbd_device = &keyboard_pc_xt_device, .fdc_device = NULL, @@ -3300,6 +3343,50 @@ const machine_t machines[] = { .net_device = NULL }, /* Has IBM AT KBC firmware. */ + { + .name = "[ISA] Multitech PC-900", + .internal_name = "mpfpc900", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_mpfpc900_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .block = CPU_BLOCK_NONE, + .min_bus = 6000000, + .max_bus = 10000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 256, + .max = 1024, + .step = 128 + }, + .nvrmask = 63, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = 0x00000000, + .kbc_p1 = 0x000004f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ { .name = "[ISA] MR BIOS 286 clone", .internal_name = "mr286", diff --git a/src/minitrace/minitrace.c b/src/minitrace/minitrace.c index 290486ec5..9762f1c55 100644 --- a/src/minitrace/minitrace.c +++ b/src/minitrace/minitrace.c @@ -419,7 +419,7 @@ void mtr_flush_with_state(int is_last) { len = snprintf(linebuf, ARRAY_SIZE(linebuf), "%s{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 ",\"ph\":\"%c\",\"name\":\"%s\",\"args\":{%s}%s}", first_line ? "" : ",\n", cat, raw->pid, raw->tid, raw->ts - time_offset, raw->ph, raw->name, arg_buf, id_buf); - fwrite(linebuf, 1, len, f); + fwrite(linebuf, 1, len, fp); first_line = 0; if (raw->arg_type == MTR_ARG_TYPE_STRING_COPY) { diff --git a/src/network/net_modem.c b/src/network/net_modem.c index af97a16db..24869349f 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -1566,6 +1566,8 @@ static const device_config_t modem_config[] = { { .description = "57600", .value = 57600 }, { .description = "56000", .value = 56000 }, { .description = "38400", .value = 38400 }, + { .description = "33600", .value = 33600 }, + { .description = "28800", .value = 28800 }, { .description = "19200", .value = 19200 }, { .description = "14400", .value = 14400 }, { .description = "9600", .value = 9600 }, diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 03bc68390..240315faa 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -267,6 +267,13 @@ plat_getcwd(char *bufp, int max) return 0; } +char * +path_get_basename(const char *path) +{ + QFileInfo fi(path); + return fi.fileName().toUtf8().data(); +} + void path_get_dirname(char *dest, const char *path) { diff --git a/src/qt/sdl_joystick.c b/src/qt/sdl_joystick.c index f1ba0380f..fddb730e7 100644 --- a/src/qt/sdl_joystick.c +++ b/src/qt/sdl_joystick.c @@ -50,9 +50,13 @@ joystick_init(void) SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1"); #endif - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) { +#ifdef __APPLE__ + if (SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0) +#else + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) +#endif return; - } + joysticks_present = SDL_NumJoysticks(); memset(sdl_joy, 0, sizeof(sdl_joy)); diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index be23a66fe..f5b81e369 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -472,7 +472,7 @@ scsi_cdrom_mode_sense_read(const scsi_cdrom_t *dev, const uint8_t pgctl, default: break; - } + } return ret; } @@ -857,11 +857,18 @@ scsi_cdrom_unit_attention(scsi_cdrom_t *dev) static void scsi_cdrom_buf_alloc(scsi_cdrom_t *dev, const uint32_t len) { - if (dev->buffer == NULL) - dev->buffer = (uint8_t *) malloc(len); + scsi_cdrom_log(dev->log, "Allocated buffer length: %i\n", len); - scsi_cdrom_log(dev->log, "Allocated buffer length: %i, buffer = %p\n", - len, dev->buffer); + if (dev->buffer == NULL) { + dev->buffer = (uint8_t *) malloc(len); + dev->buffer_sz = len; + } + + if (len > dev->buffer_sz) { + uint8_t *buf = (uint8_t *) realloc(dev->buffer, len); + dev->buffer = buf; + dev->buffer_sz = len; + } } static void @@ -1572,7 +1579,7 @@ scsi_cdrom_read(scsi_common_t *sc) dev->drv->seek_diff = 0; if (ret > 0) { - if (osl > 0) + if (osl > 0) scsi_cdrom_set_period(dev); ui_sb_update_icon(SB_CDROM | dev->id, @@ -2619,7 +2626,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) dev->sector_type, 0x00)) { scsi_cdrom_illegal_mode(dev); ret = 0; - } + } scsi_cdrom_log(dev->log, "READ (6): Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; @@ -2632,7 +2639,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) (cdb[9] & 0xc0) : 0x00)) { scsi_cdrom_illegal_mode(dev); ret = 0; - } + } scsi_cdrom_log(dev->log, "READ (10): Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; @@ -2648,7 +2655,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) (cdb[9] & 0xc0) : 0x00)) { scsi_cdrom_illegal_mode(dev); ret = 0; - } + } scsi_cdrom_log(dev->log, "READ (12): Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; @@ -2699,7 +2706,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) scsi_cdrom_buf_alloc(dev, dev->packet_len); dev->drv->seek_diff = ABS((int) (pos - dev->sector_pos)); - dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_pos = dev->sector_pos; /* Any of these commands stop the audio playing. */ cdrom_stop(dev->drv); @@ -3517,6 +3524,7 @@ atapi_out: break; case GPCMD_PAUSE_RESUME: + case GPCMD_PAUSE_RESUME_ALT: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); cdrom_audio_pause_resume(dev->drv, cdb[8] & 0x01); scsi_cdrom_command_complete(dev); diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index bfa8b42cf..9c8d36f7f 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -623,10 +623,12 @@ static void scsi_disk_buf_alloc(scsi_disk_t *dev, uint32_t len) { scsi_disk_log(dev->log, "Allocated buffer length: %i\n", len); + if (dev->temp_buffer == NULL) { dev->temp_buffer = (uint8_t *) malloc(len); dev->temp_buffer_sz = len; } + if (len > dev->temp_buffer_sz) { uint8_t *buf = (uint8_t *) realloc(dev->temp_buffer, len); dev->temp_buffer = buf; diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 04c188705..2c73066a1 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -1274,7 +1274,7 @@ esp_command_complete(void *priv, uint32_t status) static void esp_timer_on(esp_t *dev, scsi_device_t *sd, double p) { - if ((dev->rregs[ESP_CFG3] & 0x18) == 0x18) { + if ((dev->wregs[ESP_CFG3] & 0x18) == 0x18) { /* Fast SCSI: 10000000 bytes per second */ dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.1); } else { @@ -1537,11 +1537,11 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_pci_soft_reset(dev); break; case CMD_BUSRESET: - esp_log("ESP Bus Reset val=%02x.\n", (dev->rregs[ESP_CFG1] & CFG1_RESREPT)); + esp_log("ESP Bus Reset val=%02x.\n", (dev->wregs[ESP_CFG1] & CFG1_RESREPT)); for (uint8_t i = 0; i < 16; i++) scsi_device_reset(&scsi_devices[dev->bus][i]); - if (!(dev->rregs[ESP_CFG1] & CFG1_RESREPT)) { + if (!(dev->wregs[ESP_CFG1] & CFG1_RESREPT)) { dev->rregs[ESP_RINTR] |= INTR_RST; esp_log("ESP Bus Reset with IRQ\n"); esp_raise_irq(dev); @@ -1579,7 +1579,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_raise_irq(dev); break; case CMD_PAD: - esp_log("val = %02X\n", val); + esp_log("PAD=%02X\n", val); timer_stop(&dev->timer); timer_on_auto(&dev->timer, dev->period); esp_log("ESP Transfer Pad\n"); @@ -2214,7 +2214,8 @@ esp_pci_reset(void *priv) esp_pci_soft_reset(dev); esp_log("PCI Reset.\n"); - } + } else + esp_log("NULL.\n"); } static void * diff --git a/src/sound/audio4.c b/src/sound/audio4.c index 4e74d2c0c..c76d3253f 100644 --- a/src/sound/audio4.c +++ b/src/sound/audio4.c @@ -34,128 +34,146 @@ #endif #define I_NORMAL 0 -#define I_MUSIC 1 -#define I_WT 2 -#define I_CD 3 -#define I_MIDI 4 +#define I_MUSIC 1 +#define I_WT 2 +#define I_CD 3 +#define I_MIDI 4 -static int audio[5] = {-1, -1, -1, -1, -1}; +static int audio[5] = { -1, -1, -1, -1, -1 }; #ifdef USE_NEW_API static struct audio_swpar info[5]; #else static audio_info_t info[5]; #endif -static int freqs[5] = {SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0}; +static int freqs[5] = { SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0 }; -void closeal(void){ - int i; - for(i = 0; i < sizeof(audio) / sizeof(audio[0]); i++){ - if(audio[i] != -1){ - close(audio[i]); - } - audio[i] = -1; - } +void +closeal(void) +{ + for (int i = 0; i < sizeof(audio) / sizeof(audio[0]); i++) { + if (audio[i] != -1) + close(audio[i]); + + audio[i] = -1; + } } -void inital(void){ - int i; - for(i = 0; i < sizeof(audio) / sizeof(audio[0]); i++){ - audio[i] = open("/dev/audio", O_WRONLY); - if(audio[i] == -1) audio[i] = open("/dev/audio0", O_WRONLY); - if(audio[i] != -1){ +void +inital(void) +{ + for (int i = 0; i < sizeof(audio) / sizeof(audio[0]); i++) { + audio[i] = open("/dev/audio", O_WRONLY); + if (audio[i] == -1) + audio[i] = open("/dev/audio0", O_WRONLY); + if (audio[i] != -1) { #ifdef USE_NEW_API - AUDIO_INITPAR(&info[i]); - ioctl(audio[i], AUDIO_GETPAR, &info[i]); - info[i].sig = 1; - info[i].bits = 16; - info[i].pchan = 2; - info[i].bps = 2; - ioctl(audio[i], AUDIO_SETPAR, &info[i]); + AUDIO_INITPAR(&info[i]); + ioctl(audio[i], AUDIO_GETPAR, &info[i]); + info[i].sig = 1; + info[i].bits = 16; + info[i].pchan = 2; + info[i].bps = 2; + ioctl(audio[i], AUDIO_SETPAR, &info[i]); #else - AUDIO_INITINFO(&info[i]); + AUDIO_INITINFO(&info[i]); #if defined(__NetBSD__) && (__NetBSD_Version__ >= 900000000) - ioctl(audio[i], AUDIO_GETFORMAT, &info[i]); + ioctl(audio[i], AUDIO_GETFORMAT, &info[i]); #else - ioctl(audio[i], AUDIO_GETINFO, &info[i]); + ioctl(audio[i], AUDIO_GETINFO, &info[i]); #endif - info[i].play.channels = 2; - info[i].play.precision = 16; - info[i].play.encoding = AUDIO_ENCODING_SLINEAR; - info[i].hiwat = 5; - info[i].lowat = 3; - ioctl(audio[i], AUDIO_SETINFO, &info[i]); + info[i].play.channels = 2; + info[i].play.precision = 16; + info[i].play.encoding = AUDIO_ENCODING_SLINEAR; + info[i].hiwat = 5; + info[i].lowat = 3; + ioctl(audio[i], AUDIO_SETINFO, &info[i]); #endif - } - } + } + } } -void givealbuffer_common(const void *buf, const uint8_t src, const int size){ - const int freq = freqs[src]; - int16_t* output; - int output_size; - int16_t* conv; - int conv_size; - int i; - double gain; - int target_rate; - if(audio[src] == -1) return; +void +givealbuffer_common(const void *buf, const uint8_t src, const int size) +{ + const int freq = freqs[src]; + int16_t* output; + int output_size; + int16_t* conv; + int conv_size; + double gain; + int target_rate; - gain = sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0); + if(audio[src] == -1) + return; - if(sound_is_float){ - float* input = (float*)buf; - conv_size = sizeof(int16_t) * size; - conv = malloc(conv_size); - for(i = 0; i < conv_size / sizeof(int16_t); i++){ - conv[i] = 32767 * input[i]; - } - }else{ - conv_size = size * sizeof(int16_t); - conv = malloc(conv_size); - memcpy(conv, buf, conv_size); - } + gain = sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0); + + if (sound_is_float) { + float* input = (float*)buf; + conv_size = sizeof(int16_t) * size; + conv = malloc(conv_size); + for (int i = 0; i < conv_size / sizeof(int16_t); i++) + conv[i] = 32767 * input[i]; + } else { + conv_size = size * sizeof(int16_t); + conv = malloc(conv_size); + memcpy(conv, buf, conv_size); + } #ifdef USE_NEW_API - target_rate = info[src].rate; + target_rate = info[src].rate; #else - target_rate = info[src].play.sample_rate; + target_rate = info[src].play.sample_rate; #endif - output_size = (double)conv_size * target_rate / freq; - output_size -= output_size % 4; - output = malloc(output_size); - - for(i = 0; i < output_size / sizeof(int16_t) / 2; i++){ - int ind = i * freq / target_rate * 2; - output[i * 2 + 0] = conv[ind + 0] * gain; - output[i * 2 + 1] = conv[ind + 1] * gain; - } + output_size = (double) conv_size * target_rate / freq; + output_size -= output_size % 4; + output = malloc(output_size); + + for (int i = 0; i < output_size / sizeof(int16_t) / 2; i++) { + int ind = i * freq / target_rate * 2; + output[i * 2 + 0] = conv[ind + 0] * gain; + output[i * 2 + 1] = conv[ind + 1] * gain; + } - write(audio[src], output, output_size); + write(audio[src], output, output_size); - free(conv); - free(output); + free(conv); + free(output); } -void givealbuffer(const void *buf){ - givealbuffer_common(buf, I_NORMAL, SOUNDBUFLEN << 1); +void +givealbuffer(const void *buf) +{ + givealbuffer_common(buf, I_NORMAL, SOUNDBUFLEN << 1); } -void givealbuffer_music(const void *buf){ - givealbuffer_common(buf, I_MUSIC, MUSICBUFLEN << 1); +void +givealbuffer_music(const void *buf) +{ + givealbuffer_common(buf, I_MUSIC, MUSICBUFLEN << 1); } -void givealbuffer_wt(const void *buf){ - givealbuffer_common(buf, I_WT, WTBUFLEN << 1); +void +givealbuffer_wt(const void *buf) +{ + givealbuffer_common(buf, I_WT, WTBUFLEN << 1); } -void givealbuffer_cd(const void *buf){ - givealbuffer_common(buf, I_CD, CD_BUFLEN << 1); +void +givealbuffer_cd(const void *buf) +{ + givealbuffer_common(buf, I_CD, CD_BUFLEN << 1); } -void givealbuffer_midi(const void *buf, const uint32_t size){ - givealbuffer_common(buf, I_MIDI, (int) size); + +void +givealbuffer_midi(const void *buf, const uint32_t size) +{ + givealbuffer_common(buf, I_MIDI, (int) size); } - -void al_set_midi(const int freq, UNUSED(const int buf_size)){ - freqs[I_MIDI] = freq; + +void +al_set_midi(const int freq, UNUSED(const int buf_size)) +{ + freqs[I_MIDI] = freq; } diff --git a/src/sound/openal.c b/src/sound/openal.c index 90f626362..c2addb270 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -37,6 +37,12 @@ #define FREQ SOUND_FREQ #define BUFLEN SOUNDBUFLEN +#define I_NORMAL 0 +#define I_MUSIC 1 +#define I_WT 2 +#define I_CD 3 +#define I_MIDI 4 + ALuint buffers[4]; /* front and back buffers */ ALuint buffers_music[4]; /* front and back buffers */ ALuint buffers_wt[4]; /* front and back buffers */ @@ -124,7 +130,7 @@ inital(void) int16_t *cd_buf_int16 = NULL; int16_t *midi_buf_int16 = NULL; - int init_midi = 0; + int init_midi = 0; if (initialized) return; @@ -166,32 +172,36 @@ inital(void) else alGenSources(4, source); - alSource3f(source[0], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[0], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[0], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[0], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[0], AL_SOURCE_RELATIVE, AL_TRUE); - alSource3f(source[1], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[1], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[1], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[1], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[1], AL_SOURCE_RELATIVE, AL_TRUE); - alSource3f(source[2], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[2], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[2], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[2], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[2], AL_SOURCE_RELATIVE, AL_TRUE); - alSource3f(source[3], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[3], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[3], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[3], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[3], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(source[I_NORMAL], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_NORMAL], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_NORMAL], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_NORMAL], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_NORMAL], AL_SOURCE_RELATIVE, AL_TRUE); + + alSource3f(source[I_MUSIC], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_MUSIC], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_MUSIC], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_MUSIC], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_MUSIC], AL_SOURCE_RELATIVE, AL_TRUE); + + alSource3f(source[I_WT], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_WT], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_WT], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_WT], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_WT], AL_SOURCE_RELATIVE, AL_TRUE); + + alSource3f(source[I_CD], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_CD], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_CD], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_CD], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_CD], AL_SOURCE_RELATIVE, AL_TRUE); + if (init_midi) { - alSource3f(source[4], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[4], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[4], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[4], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[4], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(source[I_MIDI], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_MIDI], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_MIDI], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_MIDI], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_MIDI], AL_SOURCE_RELATIVE, AL_TRUE); } if (sound_is_float) { @@ -228,18 +238,18 @@ inital(void) } } - alSourceQueueBuffers(source[0], 4, buffers); - alSourceQueueBuffers(source[1], 4, buffers_music); - alSourceQueueBuffers(source[2], 4, buffers_wt); - alSourceQueueBuffers(source[3], 4, buffers_cd); + alSourceQueueBuffers(source[I_NORMAL], 4, buffers); + alSourceQueueBuffers(source[I_MUSIC], 4, buffers_music); + alSourceQueueBuffers(source[I_WT], 4, buffers_wt); + alSourceQueueBuffers(source[I_CD], 4, buffers_cd); if (init_midi) - alSourceQueueBuffers(source[4], 4, buffers_midi); - alSourcePlay(source[0]); - alSourcePlay(source[1]); - alSourcePlay(source[2]); - alSourcePlay(source[3]); + alSourceQueueBuffers(source[I_MIDI], 4, buffers_midi); + alSourcePlay(source[I_NORMAL]); + alSourcePlay(source[I_MUSIC]); + alSourcePlay(source[I_WT]); + alSourcePlay(source[I_CD]); if (init_midi) - alSourcePlay(source[4]); + alSourcePlay(source[I_MIDI]); if (sound_is_float) { if (init_midi) diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index c32c16be1..b806f3ccb 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -556,11 +556,11 @@ emu8k_inw(uint16_t addr, void *priv) return ret; case 4: - READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4); + READ16(addr, emu8k->voice[emu8k->cur_voice].z2); return ret; case 5: - READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5); + READ16(addr, emu8k->voice[emu8k->cur_voice].z1); return ret; case 6: @@ -888,11 +888,11 @@ emu8k_outw(uint16_t addr, uint16_t val, void *priv) return; case 4: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4, val); + WRITE16(addr, emu8k->voice[emu8k->cur_voice].z2, val); return; case 5: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5, val); + WRITE16(addr, emu8k->voice[emu8k->cur_voice].z1, val); return; case 6: @@ -1006,7 +1006,7 @@ emu8k_outw(uint16_t addr, uint16_t val, void *priv) case 0x9: emu8k->reverb_engine.reflections[0].feedback = (val & 0xF) / 15.0; break; - case 0xB: + case 0xB: #if 0 emu8k->reverb_engine.reflections[0].feedback_r = (val&0xF)/15.0; #endif @@ -1050,7 +1050,7 @@ emu8k_outw(uint16_t addr, uint16_t val, void *priv) case 1: emu8k->reverb_engine.refl_in_amp = val & 0xFF; break; - case 3: + case 3: #if 0 emu8k->reverb_engine.refl_in_amp_r = val&0xFF; #endif @@ -1811,11 +1811,10 @@ emu8k_update(emu8k_t *emu8k) emu_voice->filt_buffer[1] += (emu_voice->filt_buffer[0] * coef0) >> 24; emu_voice->filt_buffer[0] += (vhp * coef0) >> 24; dat = (int32_t) (emu_voice->filt_buffer[1] >> 8); - if (dat > 32767) { + if (dat > 32767) dat = 32767; - } else if (dat < -32768) { + else if (dat < -32768) dat = -32768; - } #elif defined FILTER_MOOG @@ -1823,15 +1822,15 @@ emu8k_update(emu8k_t *emu8k) dat <<= 8; dat -= (coef2 * emu_voice->filt_buffer[4]) >> 24; /*feedback*/ - int64_t t1 = emu_voice->filt_buffer[1]; + int64_t t1 = emu_voice->filt_buffer[1]; emu_voice->filt_buffer[1] = ((dat + emu_voice->filt_buffer[0]) * coef0 - emu_voice->filt_buffer[1] * coef1) >> 24; emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); - int64_t t2 = emu_voice->filt_buffer[2]; + int64_t t2 = emu_voice->filt_buffer[2]; emu_voice->filt_buffer[2] = ((emu_voice->filt_buffer[1] + t1) * coef0 - emu_voice->filt_buffer[2] * coef1) >> 24; emu_voice->filt_buffer[2] = ClipBuffer(emu_voice->filt_buffer[2]); - int64_t t3 = emu_voice->filt_buffer[3]; + int64_t t3 = emu_voice->filt_buffer[3]; emu_voice->filt_buffer[3] = ((emu_voice->filt_buffer[2] + t2) * coef0 - emu_voice->filt_buffer[3] * coef1) >> 24; emu_voice->filt_buffer[3] = ClipBuffer(emu_voice->filt_buffer[3]); @@ -1841,11 +1840,10 @@ emu8k_update(emu8k_t *emu8k) emu_voice->filt_buffer[0] = ClipBuffer(dat); dat = (int32_t) (emu_voice->filt_buffer[4] >> 8); - if (dat > 32767) { + if (dat > 32767) dat = 32767; - } else if (dat < -32768) { + else if (dat < -32768) dat = -32768; - } #elif defined FILTER_CONSTANT @@ -1864,11 +1862,10 @@ emu8k_update(emu8k_t *emu8k) emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); dat = (int32_t) (emu_voice->filt_buffer[1] >> 8); - if (dat > 32767) { + if (dat > 32767) dat = 32767; - } else if (dat < -32768) { + else if (dat < -32768) dat = -32768; - } #endif } @@ -2372,6 +2369,8 @@ emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) void emu8k_close(emu8k_t *emu8k) { - free(emu8k->rom); - free(emu8k->ram); + if (emu8k->rom) + free(emu8k->rom); + if (emu8k->ram) + free(emu8k->ram); } diff --git a/src/sound/sndio.c b/src/sound/sndio.c index 2fe1434df..7459dc130 100644 --- a/src/sound/sndio.c +++ b/src/sound/sndio.c @@ -32,109 +32,125 @@ #define I_CD 3 #define I_MIDI 4 -static struct sio_hdl* audio[5] = {NULL, NULL, NULL, NULL, NULL}; +static struct sio_hdl* audio[5] = { NULL, NULL, NULL, NULL, NULL }; static struct sio_par info[5]; -static int freqs[5] = {SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0}; +static int freqs[5] = { SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0 }; -void closeal(void){ - int i; - for(i = 0; i < sizeof(audio) / sizeof(audio[0]); i++){ - if(audio[i] != NULL){ - sio_close(audio[i]); - } - audio[i] = NULL; - } +void +closeal(void) +{ + for (int i = 0; i < sizeof(audio) / sizeof(audio[0]); i++) { + if (audio[i] != NULL) + sio_close(audio[i]); + + audio[i] = NULL; + } } -void inital(void){ - int i; - for(i = 0; i < sizeof(audio) / sizeof(audio[0]); i++){ - audio[i] = sio_open(SIO_DEVANY, SIO_PLAY, 0); - if(audio[i] != NULL){ - int rate; - int max_frames; - sio_getpar(audio[i], &info[i]); - rate = info[i].rate; - max_frames = info[i].bufsz; - sio_initpar(&info[i]); - info[i].sig = 1; - info[i].bits = 16; - info[i].pchan = 2; - info[i].rate = rate; - info[i].appbufsz = max_frames; - sio_setpar(audio[i], &info[i]); - sio_getpar(audio[i], &info[i]); - if(!sio_start(audio[i])){ - sio_close(audio[i]); - audio[i] = NULL; - } - } - } +void +inital(void) +{ + for (int i = 0; i < sizeof(audio) / sizeof(audio[0]); i++) { + audio[i] = sio_open(SIO_DEVANY, SIO_PLAY, 0); + if (audio[i] != NULL) { + int rate; + int max_frames; + sio_getpar(audio[i], &info[i]); + rate = info[i].rate; + max_frames = info[i].bufsz; + sio_initpar(&info[i]); + info[i].sig = 1; + info[i].bits = 16; + info[i].pchan = 2; + info[i].rate = rate; + info[i].appbufsz = max_frames; + sio_setpar(audio[i], &info[i]); + sio_getpar(audio[i], &info[i]); + if (!sio_start(audio[i])) { + sio_close(audio[i]); + audio[i] = NULL; + } + } + } } -void givealbuffer_common(const void *buf, const uint8_t src, const int size){ - const int freq = freqs[src]; - int16_t* output; - int output_size; - int16_t* conv; - int conv_size; - int i; - double gain; - int target_rate; - if(audio[src] == NULL) return; +void +givealbuffer_common(const void *buf, const uint8_t src, const int size) +{ + const int freq = freqs[src]; + int16_t* output; + int output_size; + int16_t* conv; + int conv_size; + double gain; + int target_rate; + if (audio[src] == NULL) + return; - gain = sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0); + gain = sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0); - if(sound_is_float){ - float* input = (float*)buf; - conv_size = sizeof(int16_t) * size; - conv = malloc(conv_size); - for(i = 0; i < conv_size / sizeof(int16_t); i++){ - conv[i] = 32767 * input[i]; - } - }else{ - conv_size = size * sizeof(int16_t); - conv = malloc(conv_size); - memcpy(conv, buf, conv_size); - } + if (sound_is_float) { + float* input = (float*) buf; + conv_size = sizeof(int16_t) * size; + conv = malloc(conv_size); + for (int i = 0; i < conv_size / sizeof(int16_t); i++) + conv[i] = 32767 * input[i]; + } else { + conv_size = size * sizeof(int16_t); + conv = malloc(conv_size); + memcpy(conv, buf, conv_size); + } - target_rate = info[src].rate; + target_rate = info[src].rate; - output_size = (double)conv_size * target_rate / freq; - output_size -= output_size % 4; - output = malloc(output_size); - - for(i = 0; i < output_size / sizeof(int16_t) / 2; i++){ - int ind = i * freq / target_rate * 2; - output[i * 2 + 0] = conv[ind + 0] * gain; - output[i * 2 + 1] = conv[ind + 1] * gain; - } + output_size = (double) conv_size * target_rate / freq; + output_size -= output_size % 4; + output = malloc(output_size); + + for (int i = 0; i < output_size / sizeof(int16_t) / 2; i++) { + int ind = i * freq / target_rate * 2; + output[i * 2 + 0] = conv[ind + 0] * gain; + output[i * 2 + 1] = conv[ind + 1] * gain; + } - sio_write(audio[src], output, output_size); + sio_write(audio[src], output, output_size); - free(conv); - free(output); + free(conv); + free(output); } -void givealbuffer(const void *buf){ - givealbuffer_common(buf, I_NORMAL, SOUNDBUFLEN << 1); +void +givealbuffer(const void *buf) +{ + givealbuffer_common(buf, I_NORMAL, SOUNDBUFLEN << 1); } -void givealbuffer_music(const void *buf){ - givealbuffer_common(buf, I_MUSIC, MUSICBUFLEN << 1); +void +givealbuffer_music(const void *buf) +{ + givealbuffer_common(buf, I_MUSIC, MUSICBUFLEN << 1); } -void givealbuffer_wt(const void *buf){ - givealbuffer_common(buf, I_WT, WTBUFLEN << 1); +void +givealbuffer_wt(const void *buf) +{ + givealbuffer_common(buf, I_WT, WTBUFLEN << 1); } -void givealbuffer_cd(const void *buf){ - givealbuffer_common(buf, I_CD, CD_BUFLEN << 1); +void +givealbuffer_cd(const void *buf) +{ + givealbuffer_common(buf, I_CD, CD_BUFLEN << 1); } -void givealbuffer_midi(const void *buf, const uint32_t size){ - givealbuffer_common(buf, I_MIDI, (int) size); + +void +givealbuffer_midi(const void *buf, const uint32_t size) +{ + givealbuffer_common(buf, I_MIDI, (int) size); } - -void al_set_midi(const int freq, UNUSED(const int buf_size)){ - freqs[I_MIDI] = freq; + +void +al_set_midi(const int freq, UNUSED(const int buf_size)) +{ + freqs[I_MIDI] = freq; } diff --git a/src/sound/sound.c b/src/sound/sound.c index c81dc47b0..579056359 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -55,7 +55,6 @@ int wavetable_pos_global = 0; int sound_gain = 0; static sound_handler_t sound_handlers[8]; - static sound_handler_t music_handlers[8]; static sound_handler_t wavetable_handlers[8]; diff --git a/src/sound/xaudio2.c b/src/sound/xaudio2.c index 2aee97efc..b526fa72f 100644 --- a/src/sound/xaudio2.c +++ b/src/sound/xaudio2.c @@ -39,8 +39,8 @@ static void *xaudio2_handle = NULL; static HRESULT(WINAPI *pXAudio2Create)(IXAudio2 **ppXAudio2, uint32_t Flags, XAUDIO2_PROCESSOR XAudio2Processor); static dllimp_t xaudio2_imports[] = { - {"XAudio2Create", &pXAudio2Create}, - { NULL, NULL }, + {"XAudio2Create", &pXAudio2Create }, + { NULL, NULL }, }; # define XAudio2Create pXAudio2Create #endif @@ -119,22 +119,18 @@ void inital(void) { #if defined(_WIN32) && !defined(USE_FAUDIO) - if (xaudio2_handle == NULL) { + if (xaudio2_handle == NULL) xaudio2_handle = dynld_module("xaudio2_9.dll", xaudio2_imports); - } - if (xaudio2_handle == NULL) { + if (xaudio2_handle == NULL) xaudio2_handle = dynld_module("xaudio2_9redist.dll", xaudio2_imports); - } - if (xaudio2_handle == NULL) { + if (xaudio2_handle == NULL) return; - } #endif - if (XAudio2Create(&xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR)) { + if (XAudio2Create(&xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR)) return; - } if (IXAudio2_CreateMasteringVoice(xaudio2, &mastervoice, 2, FREQ, 0, 0, NULL, 0)) { IXAudio2_Release(xaudio2); @@ -209,6 +205,7 @@ closeal(void) { if (!initialized) return; + initialized = 0; (void) IXAudio2SourceVoice_Stop(srcvoice, 0, XAUDIO2_COMMIT_NOW); (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoice); @@ -229,9 +226,11 @@ closeal(void) IXAudio2SourceVoice_DestroyVoice(srcvoice); IXAudio2MasteringVoice_DestroyVoice(mastervoice); IXAudio2_Release(xaudio2); - srcvoice = srcvoicecd = srcvoicemidi = NULL; - mastervoice = NULL; - xaudio2 = NULL; + srcvoice = NULL; + srcvoicecd = NULL; + srcvoicemidi = NULL; + mastervoice = NULL; + xaudio2 = NULL; #if defined(_WIN32) && !defined(USE_FAUDIO) dynld_close(xaudio2_handle); diff --git a/src/unix/unix.c b/src/unix/unix.c index de35f4e93..4f3990590 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -351,7 +351,7 @@ plat_put_backslash(char *s) /* Return the last element of a pathname. */ char * -plat_get_basename(const char *path) +path_get_basename(const char *path) { int c = (int) strlen(path); @@ -1420,6 +1420,7 @@ main(int argc, char **argv) f_rl_callback_handler_remove(); return 0; } + char * plat_vidapi_name(UNUSED(int i)) { diff --git a/src/video/clockgen/vid_clockgen_icd2061.c b/src/video/clockgen/vid_clockgen_icd2061.c index 7b80a5484..f1925e769 100644 --- a/src/video/clockgen/vid_clockgen_icd2061.c +++ b/src/video/clockgen/vid_clockgen_icd2061.c @@ -29,10 +29,15 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> +#include <86box/mem.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> #include <86box/plat_unused.h> typedef struct icd2061_t { - float freq[3]; + float freq[3]; + float ref_clock; int count; int bit_count; @@ -121,7 +126,7 @@ icd2061_write(void *priv, int val) q = qa + 2; /* Q (ICD2061) / M (ICS9161) */ ps = (icd2061->ctrl & (1 << a)) ? 4 : 2; /* Prescale */ - icd2061->freq[a] = ((float) (p_ * ps) / (float) (q * m)) * 14318184.0f; + icd2061->freq[a] = ((float) (p_ * ps) / (float) (q * m)) * icd2061->ref_clock; icd2061_log("P = %02X, M = %01X, Q = %02X, freq[%i] = %f\n", p_, m, q, a, icd2061->freq[a]); } else if (a == 6) { @@ -149,12 +154,24 @@ icd2061_getclock(int clock, void *priv) return icd2061->freq[clock]; } +void +icd2061_set_ref_clock(void *priv, svga_t *svga, float ref_clock) +{ + icd2061_t *icd2061 = (icd2061_t *) priv; + + if (icd2061) + icd2061->ref_clock = ref_clock; + + svga_recalctimings(svga); +} + static void * icd2061_init(UNUSED(const device_t *info)) { icd2061_t *icd2061 = (icd2061_t *) malloc(sizeof(icd2061_t)); memset(icd2061, 0, sizeof(icd2061_t)); + icd2061->ref_clock = 14318184.0f; icd2061->freq[0] = 25175000.0; icd2061->freq[1] = 28322000.0; icd2061->freq[2] = 28322000.0; diff --git a/src/video/ramdac/vid_ramdac_sc1502x.c b/src/video/ramdac/vid_ramdac_sc1502x.c index 1c7d4014d..4fc603ee9 100644 --- a/src/video/ramdac/vid_ramdac_sc1502x.c +++ b/src/video/ramdac/vid_ramdac_sc1502x.c @@ -33,65 +33,32 @@ typedef struct sc1502x_ramdac_t { int state; + int use_rs2; uint8_t ctrl; uint8_t idx; uint8_t regs[256]; uint32_t pixel_mask; - uint8_t enable_ext; } sc1502x_ramdac_t; static void -sc1502x_ramdac_bpp(uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga) +sc1502x_ramdac_bpp(sc1502x_ramdac_t *ramdac, svga_t *svga) { - int oldbpp = 0; - if (val == 0xff) - return; - 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; - - default: - break; - } - break; - case 4: - case 5: - svga->bpp = 15; - break; - case 6: + int oldbpp = svga->bpp; + if (ramdac->ctrl & 0x80) { + if (ramdac->ctrl & 0x40) { svga->bpp = 16; - break; - case 7: - if (val & 4) { - switch (val & 0x20) { - case 0x00: - svga->bpp = 32; - break; - case 0x20: - svga->bpp = 24; - break; - - default: - break; - } - } else - svga->bpp = 16; - break; - - default: - break; + } else + svga->bpp = 15; + } else { + if (ramdac->ctrl & 0x40) { + if (ramdac->regs[0x10] & 0x01) + svga->bpp = 32; + else if (ramdac->ctrl & 0x20) + svga->bpp = 24; + else + svga->bpp = 32; + } else + svga->bpp = 8; } if (oldbpp != svga->bpp) svga_recalctimings(svga); @@ -104,29 +71,30 @@ sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) switch (addr) { case 0x3C6: - if (ramdac->state == 0) - ramdac->enable_ext = (val == 0x10); - - if (ramdac->state == 4) { + if ((ramdac->state == 4) || (ramdac->ctrl & 0x10)) { ramdac->state = 0; - sc1502x_ramdac_bpp(val, ramdac, svga); + ramdac->ctrl = val; + if (val != 0xff) + sc1502x_ramdac_bpp(ramdac, svga); return; } ramdac->state = 0; + svga_out(addr, val, svga); break; case 0x3C7: - if (ramdac->enable_ext) { + if (ramdac->ctrl & 0x10) ramdac->idx = val; - return; - } + else + svga_out(addr, val, svga); + ramdac->state = 0; break; case 0x3C8: - if (ramdac->enable_ext) { + if (ramdac->ctrl & 0x10) { switch (ramdac->idx) { case 8: - ramdac->regs[ramdac->idx] = val; - svga_set_ramdac_type(svga, (ramdac->regs[ramdac->idx] & 1) ? RAMDAC_8BIT : RAMDAC_6BIT); + ramdac->regs[8] = val; + svga->ramdac_type = (val & 0x01) ? RAMDAC_8BIT : RAMDAC_6BIT; break; case 0x0d: ramdac->pixel_mask = val & svga->dac_mask; @@ -137,24 +105,96 @@ sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) case 0x0f: ramdac->pixel_mask |= ((val & svga->dac_mask) << 16); break; + case 0x10: + ramdac->regs[0x10] = val; + sc1502x_ramdac_bpp(ramdac, svga); + break; default: ramdac->regs[ramdac->idx] = val; break; } - return; - } + } else + svga_out(addr, val, svga); + ramdac->state = 0; break; case 0x3C9: - if (ramdac->enable_ext) - return; ramdac->state = 0; + svga_out(addr, val, svga); break; default: break; } - svga_out(addr, val, svga); +} + +void +sc1502x_rs2_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) +{ + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; + uint8_t rs = (addr & 0x03); + rs |= ((!!rs2) << 2); + + switch (rs) { + case 0x00: + if (ramdac->ctrl & 0x10) { + switch (ramdac->idx) { + case 8: + ramdac->regs[8] = val; + svga->ramdac_type = (val & 0x01) ? RAMDAC_8BIT : RAMDAC_6BIT; + break; + case 0x0d: + ramdac->pixel_mask = val & svga->dac_mask; + break; + case 0x0e: + ramdac->pixel_mask |= ((val & svga->dac_mask) << 8); + break; + case 0x0f: + ramdac->pixel_mask |= ((val & svga->dac_mask) << 16); + break; + case 0x10: + ramdac->regs[0x10] = val; + sc1502x_ramdac_bpp(ramdac, svga); + break; + default: + ramdac->regs[ramdac->idx] = val; + break; + } + } else + svga_out(addr, val, svga); + break; + case 0x01: + svga_out(addr, val, svga); + break; + case 0x02: + if (ramdac->ctrl & 0x10) { + ramdac->ctrl = val; + if (val != 0xff) + sc1502x_ramdac_bpp(ramdac, svga); + } else + svga_out(addr, val, svga); + break; + case 0x03: + if (ramdac->ctrl & 0x10) + ramdac->idx = val; + else + svga_out(addr, val, svga); + break; + case 0x04: + case 0x05: + case 0x07: + svga_out(addr, val, svga); + break; + case 0x06: + ramdac->ctrl = val; + if (val != 0xff) + sc1502x_ramdac_bpp(ramdac, svga); + break; + + default: + svga_out(addr, val, svga); + break; + } } uint8_t @@ -166,8 +206,7 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) switch (addr) { case 0x3C6: if (ramdac->state == 4) { - ramdac->state = 0; - temp = ramdac->ctrl; + temp = ramdac->ctrl; break; } ramdac->state++; @@ -176,7 +215,7 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) ramdac->state = 0; break; case 0x3C8: - if (ramdac->enable_ext) { + if (ramdac->ctrl & 0x10) { switch (ramdac->idx) { case 9: temp = 0x53; @@ -203,14 +242,72 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) temp = ramdac->regs[ramdac->idx]; break; } - } else - ramdac->state = 0; + } + ramdac->state = 0; break; case 0x3C9: - if (ramdac->enable_ext) + if (ramdac->ctrl & 0x10) temp = ramdac->idx; - else - ramdac->state = 0; + + ramdac->state = 0; + break; + + default: + break; + } + + return temp; +} + +uint8_t +sc1502x_rs2_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) +{ + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; + uint8_t rs = (addr & 0x03); + uint8_t temp = svga_in(addr, svga); + rs |= ((!!rs2) << 2); + + switch (rs) { + case 0x00: + if (ramdac->ctrl & 0x10) { + switch (ramdac->idx) { + case 9: + temp = 0x53; + break; + case 0x0a: + temp = 0x3a; + break; + case 0x0b: + temp = 0xb1; + break; + case 0x0c: + temp = 0x41; + break; + case 0x0d: + temp = ramdac->pixel_mask & 0xff; + break; + case 0x0e: + temp = ramdac->pixel_mask >> 8; + break; + case 0x0f: + temp = ramdac->pixel_mask >> 16; + break; + default: + temp = ramdac->regs[ramdac->idx]; + break; + } + } + break; + case 0x01: + if (ramdac->ctrl & 0x10) + temp = ramdac->idx; + break; + case 0x02: + if (ramdac->ctrl & 0x10) + temp = ramdac->ctrl; + break; + case 0x06: + temp = ramdac->ctrl; break; default: @@ -221,7 +318,7 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) } static void * -sc1502x_ramdac_init(UNUSED(const device_t *info)) +sc1502x_ramdac_init(const device_t *info) { sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) malloc(sizeof(sc1502x_ramdac_t)); memset(ramdac, 0, sizeof(sc1502x_ramdac_t)); @@ -254,3 +351,17 @@ const device_t sc1502x_ramdac_device = { .force_redraw = NULL, .config = NULL }; + +const device_t sc1502x_rs2_ramdac_device = { + .name = "Sierra SC1502x RAMDAC with RS2", + .internal_name = "sc1502x_rs2_ramdac", + .flags = 0, + .local = 1, + .init = sc1502x_ramdac_init, + .close = sc1502x_ramdac_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 32a402ec5..7b747ddc0 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -3674,143 +3674,147 @@ ibm8514_poll(void *priv) ibm8514_log("IBM 8514/A poll=%x offtime=%" PRIu64 ", ontime=%" PRIu64 ".\n", dev->on, dev->dispofftime, dev->dispontime); if (dev->on) { ibm8514_log("ON!\n"); - if (!dev->linepos) { - if ((dev->displine == ((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y)) && dev->hwcursor_latch.ena) { - dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff; - dev->hwcursor_oddeven = 0; - } - - if ((dev->displine == (((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y) + 1)) && dev->hwcursor_latch.ena && dev->interlace) { - dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1); - dev->hwcursor_oddeven = 1; - } - - timer_advance_u64(&svga->timer, dev->dispofftime); - svga->cgastat |= 1; - dev->linepos = 1; - - if (dev->dispon) { - dev->hdisp_on = 1; - - dev->memaddr &= dev->vram_mask; - - if (dev->firstline == 2000) { - dev->firstline = dev->displine; - video_wait_for_buffer_monitor(svga->monitor_index); + if (svga->override) + svga_set_poll(svga); + else { + if (!dev->linepos) { + if ((dev->displine == ((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y)) && dev->hwcursor_latch.ena) { + dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff; + dev->hwcursor_oddeven = 0; } - if (dev->hwcursor_on) - dev->changedvram[dev->memaddr >> 12] = dev->changedvram[(dev->memaddr >> 12) + 1] = dev->interlace ? 3 : 2; + if ((dev->displine == (((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y) + 1)) && dev->hwcursor_latch.ena && dev->interlace) { + dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1); + dev->hwcursor_oddeven = 1; + } - svga->render8514(svga); + timer_advance_u64(&svga->timer, dev->dispofftime); + svga->cgastat |= 1; + dev->linepos = 1; - svga->x_add = svga->left_overscan; - ibm8514_render_overscan_left(dev, svga); - ibm8514_render_overscan_right(dev, svga); - svga->x_add = svga->left_overscan; + if (dev->dispon) { + dev->hdisp_on = 1; - if (dev->hwcursor_on) { - if (svga->hwcursor_draw) - svga->hwcursor_draw(svga, (dev->displine + svga->y_add + ((dev->hwcursor_latch.y >= 0) ? 0 : dev->hwcursor_latch.y)) & 2047); - dev->hwcursor_on--; - if (dev->hwcursor_on && dev->interlace) + dev->memaddr &= dev->vram_mask; + + if (dev->firstline == 2000) { + dev->firstline = dev->displine; + video_wait_for_buffer_monitor(svga->monitor_index); + } + + if (dev->hwcursor_on) + dev->changedvram[dev->memaddr >> 12] = dev->changedvram[(dev->memaddr >> 12) + 1] = dev->interlace ? 3 : 2; + + svga->render8514(svga); + + svga->x_add = svga->left_overscan; + ibm8514_render_overscan_left(dev, svga); + ibm8514_render_overscan_right(dev, svga); + svga->x_add = svga->left_overscan; + + if (dev->hwcursor_on) { + if (svga->hwcursor_draw) + svga->hwcursor_draw(svga, (dev->displine + svga->y_add + ((dev->hwcursor_latch.y >= 0) ? 0 : dev->hwcursor_latch.y)) & 2047); dev->hwcursor_on--; + if (dev->hwcursor_on && dev->interlace) + dev->hwcursor_on--; + } + + if (dev->lastline < dev->displine) + dev->lastline = dev->displine; } - if (dev->lastline < dev->displine) - dev->lastline = dev->displine; - } - - dev->displine++; - if (dev->interlace) dev->displine++; - if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) - svga->cgastat &= ~8; - svga->vslines++; - if (dev->displine > 2000) - dev->displine = 0; - } else { - timer_advance_u64(&svga->timer, dev->dispontime); - if (dev->dispon) - svga->cgastat &= ~1; - dev->hdisp_on = 0; + if (dev->interlace) + dev->displine++; + if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) + svga->cgastat &= ~8; + svga->vslines++; + if (dev->displine > 2000) + dev->displine = 0; + } else { + timer_advance_u64(&svga->timer, dev->dispontime); + if (dev->dispon) + svga->cgastat &= ~1; + dev->hdisp_on = 0; - dev->linepos = 0; - if (dev->dispon) { - if (dev->scanline == dev->rowcount) { - dev->scanline = 0; - dev->memaddr_backup += (dev->rowoffset << 3); - if (dev->interlace) + dev->linepos = 0; + if (dev->dispon) { + if (dev->scanline == dev->rowcount) { + dev->scanline = 0; dev->memaddr_backup += (dev->rowoffset << 3); + if (dev->interlace) + dev->memaddr_backup += (dev->rowoffset << 3); - dev->memaddr_backup &= dev->vram_mask; - dev->memaddr = dev->memaddr_backup; - } else { - dev->scanline++; - dev->scanline &= 0x1f; - dev->memaddr = dev->memaddr_backup; - } - } - - dev->vc++; - dev->vc &= 0xfff; - - if (dev->vc == dev->dispend) { - dev->vblank_start(svga); - ibm8514_log("VBLANK irq.\n"); - dev->dispon = 0; - - for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) { - if (dev->changedvram[x]) - dev->changedvram[x]--; + dev->memaddr_backup &= dev->vram_mask; + dev->memaddr = dev->memaddr_backup; + } else { + dev->scanline++; + dev->scanline &= 0x1f; + dev->memaddr = dev->memaddr_backup; + } } - if (svga->fullchange) - svga->fullchange--; - } - if (dev->vc == dev->v_syncstart) { - dev->dispon = 0; - svga->cgastat |= 8; - x = dev->h_disp; + dev->vc++; + dev->vc &= 0xfff; - if (dev->interlace && !dev->oddeven) - dev->lastline++; - if (dev->interlace && dev->oddeven) - dev->firstline--; + if (dev->vc == dev->dispend) { + dev->vblank_start(svga); + ibm8514_log("VBLANK irq.\n"); + dev->dispon = 0; - wx = x; - wy = dev->lastline - dev->firstline; - svga_doblit(wx, wy, svga); + for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) { + if (dev->changedvram[x]) + dev->changedvram[x]--; + } - dev->firstline = 2000; - dev->lastline = 0; + if (svga->fullchange) + svga->fullchange--; + } + if (dev->vc == dev->v_syncstart) { + dev->dispon = 0; + svga->cgastat |= 8; + x = dev->h_disp; - dev->firstline_draw = 2000; - dev->lastline_draw = 0; + if (dev->interlace && !dev->oddeven) + dev->lastline++; + if (dev->interlace && dev->oddeven) + dev->firstline--; - dev->oddeven ^= 1; + wx = x; + wy = dev->lastline - dev->firstline; + svga_doblit(wx, wy, svga); - svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2; - svga->vslines = 0; + dev->firstline = 2000; + dev->lastline = 0; - if (dev->interlace && dev->oddeven) - dev->memaddr = dev->memaddr_backup = (dev->rowoffset << 1); - else - dev->memaddr = dev->memaddr_backup = 0; + dev->firstline_draw = 2000; + dev->lastline_draw = 0; - dev->memaddr = (dev->memaddr << 2); - dev->memaddr_backup = (dev->memaddr_backup << 2); - } - if (dev->vc == dev->v_total) { - dev->vc = 0; - dev->scanline = (svga->crtc[0x8] & 0x1f); - dev->dispon = 1; - dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; + dev->oddeven ^= 1; - svga->x_add = svga->left_overscan; + svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2; + svga->vslines = 0; - dev->hwcursor_on = 0; - dev->hwcursor_latch = dev->hwcursor; + if (dev->interlace && dev->oddeven) + dev->memaddr = dev->memaddr_backup = (dev->rowoffset << 1); + else + dev->memaddr = dev->memaddr_backup = 0; + + dev->memaddr = (dev->memaddr << 2); + dev->memaddr_backup = (dev->memaddr_backup << 2); + } + if (dev->vc == dev->v_total) { + dev->vc = 0; + dev->scanline = (svga->crtc[0x8] & 0x1f); + dev->dispon = 1; + dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; + + svga->x_add = svga->left_overscan; + + dev->hwcursor_on = 0; + dev->hwcursor_latch = dev->hwcursor; + } } } } diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index e96bd827c..d25861681 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -149,7 +149,6 @@ ega_out(uint16_t addr, uint8_t val, void *priv) ega->vres = !(val & 0x80); ega->pallook = ega->vres ? pallook16 : pallook64; ega->vidclock = val & 4; - pclog("clock = %01X\n", (val & 0x0c) >> 2); ega->miscout = val; ega->overscan_color = ega->vres ? pallook16[ega->attrregs[0x11] & 0x0f] : pallook64[ega->attrregs[0x11] & 0x3f]; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 7fdc04e9e..564136428 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -3598,6 +3598,12 @@ dither_24_to_8(int r, int g, int b) return ((b >> 6) & 3) | (((g >> 5) & 7) << 2) | (((r >> 5) & 7) << 5); } +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) + static void blit_iload_iload(mystique_t *mystique, uint32_t data, int size) { @@ -3613,7 +3619,50 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; uint32_t data_mask = 1; + /* YUV stuff */ + int y0; + int y1; + int u; + int v; + int dR; + int dG; + int dB; + int r0; + int g0; + int b0; + int r1; + int g1; + int b1; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + y0 = (298 * ((int) (data & 0xff) - 16)) >> 8; + u = ((data >> 8) & 0xff) - 0x80; + y1 = (298 * ((int) ((data >> 16) & 0xff) - 16)) >> 8; + v = ((data >> 24) & 0xff) - 0x80; + dR = (309 * v) >> 8; + dG = (100 * u + 208 * v) >> 8; + dB = (516 * u) >> 8; + + r0 = y0 + dR; + CLAMP(r0); + g0 = y0 - dG; + CLAMP(g0); + b0 = y0 + dB; + CLAMP(b0); + r1 = y1 + dR; + CLAMP(r1); + g1 = y1 - dG; + CLAMP(g1); + b1 = y1 + dB; + CLAMP(b1); + + data64 = b0 | (g0 << 8) | (r0 << 16); + data64 |= ((uint64_t) b1 << 32) | ((uint64_t) g1 << 40) | ((uint64_t) r1 << 48); + size = 64; + + break; + } switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: bltckey &= 0xff; @@ -3947,6 +3996,65 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) mystique->dwgreg.iload_rem_data = data64; break; + case DWGCTRL_BLTMOD_BUYUV: + while (size >= 32) { + int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + { + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + + dst = bitop(dither(mystique, (data64 >> 16) & 0xFF, (data64 >> 8) & 0xFF, data64 & 0xFF, mystique->dwgreg.xdst & 1, mystique->dwgreg.selline & 1), dst, mystique->dwgreg.dwgctrl_running); + + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + } + case MACCESS_PWIDTH_8: + { + dst = ((uint8_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; + + dst = bitop(dither_24_to_8((data64 >> 16) & 0xFF, (data64 >> 8) & 0xFF, data64 & 0xFF), dst, mystique->dwgreg.dwgctrl_running); + + ((uint8_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; + break; + } + default: { + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + + dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + } + } + } + + size -= 32; + data64 >>= 32ULL; + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + data64 = 0; + size = 0; + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + mystique->dwgreg.iload_rem_count = size; + mystique->dwgreg.iload_rem_data = data64; + break; + case DWGCTRL_BLTMOD_BU32BGR: size += mystique->dwgreg.iload_rem_count; while (size >= 32) { @@ -3996,12 +4104,6 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) } } -#define CLAMP(x) \ - do { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } while (0) - static void blit_iload_iload_scale(mystique_t *mystique, uint32_t data, int size) { @@ -4053,7 +4155,7 @@ blit_iload_iload_scale(mystique_t *mystique, uint32_t data, int size) break; case MACCESS_PWIDTH_32: data64 = b0 | (g0 << 8) | (r0 << 16); - data64 |= ((uint64_t) b0 << 32) | ((uint64_t) g0 << 40) | ((uint64_t) r0 << 48); + data64 |= ((uint64_t) b1 << 32) | ((uint64_t) g1 << 40) | ((uint64_t) r1 << 48); size = 64; break; @@ -5925,6 +6027,7 @@ blit_iload(mystique_t *mystique) case DWGCTRL_BLTMOD_BMONOWF: case DWGCTRL_BLTMOD_BU24RGB: case DWGCTRL_BLTMOD_BU32RGB: + case DWGCTRL_BLTMOD_BUYUV: mystique->dwgreg.length_cur = mystique->dwgreg.length; mystique->dwgreg.xdst = mystique->dwgreg.fxleft; mystique->dwgreg.iload_rem_data = 0; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index fbf329e84..53f75365f 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -49,6 +49,9 @@ #define ROM_DIAMOND_STEALTH_VRAM "roms/video/s3/Diamond Stealth VRAM BIOS v2.31 U14.BIN" #define ROM_AMI_86C924 "roms/video/s3/S3924AMI.BIN" #define ROM_METHEUS_86C928 "roms/video/s3/928.VBI" +#define ROM_ELSAWIN1KVL_86C928 "roms/video/s3/ELSA_Winner_XHR_1000VL.BIN" +#define ROM_ELSAWIN1KPCI_86C928 "roms/video/s3/ELSA_Winner_10000_PCI_BIOS_3.04.02.BIN" +#define ROM_ELSAWIN2K_86C928 "roms/video/s3/elsa-winner-2000-vga-bios-v1-02-03-66b7554c706d6962736994.bin" #define ROM_SPEA_MERCURY_LITE_PCI "roms/video/s3/SPEAVGA.VBI" #define ROM_SPEA_MIRAGE_86C801 "roms/video/s3/V7MIRAGE.VBI" #define ROM_SPEA_MIRAGE_86C805 "roms/video/s3/86c805pspeavlbus.BIN" @@ -98,6 +101,9 @@ enum { S3_PHOENIX_86C805, S3_ORCHID_86C911, S3_METHEUS_86C928, + S3_ELSAWIN1K_86C928, + S3_ELSAWIN1KPCI_86C928, + S3_ELSAWIN2K_86C928, S3_AMI_86C924, S3_TRIO64V2_DX, S3_TRIO64V2_DX_ONBOARD, @@ -191,8 +197,19 @@ enum { FIFO_OUT_DWORD = (0x06 << 24) }; -typedef struct -{ +typedef enum { + BUILT_IN = 0, + SC1148X, + SC1502X, + ATT49X, + ATT498, + BT48X, + IBM_RGB, + S3_SDAC, + TVP3026 +} s3_ramdac_type; + +typedef struct { uint32_t addr_type; uint32_t val; } fifo_entry_t; @@ -204,6 +221,8 @@ typedef struct s3_t { mem_mapping_t new_mmio_mapping; int elsa_eeprom; + s3_ramdac_type ramdac_type; + uint8_t has_bios; rom_t bios_rom; @@ -811,6 +830,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) { svga_t *svga = &s3->svga; + s3_log("OUTB FIFO=%04x, val=%02x.\n", port, val); switch (port) { case 0x8148: case 0x82e8: @@ -1519,14 +1539,17 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xd148: case 0xd2e8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); s3->accel.ropmix = (s3->accel.ropmix & 0xff00) | val; break; case 0xd149: case 0xd2e9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); s3->accel.ropmix = (s3->accel.ropmix & 0x00ff) | (val << 8); break; case 0xe548: case 0xe6e8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); @@ -1537,6 +1560,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe549: case 0xe6e9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); @@ -1550,6 +1574,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe54a: case 0xe6ea: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); else if (s3->bpp == 3) { @@ -1561,6 +1586,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe54b: case 0xe6eb: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); else if (s3->bpp == 3) { @@ -1578,7 +1604,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe949: case 0xeae9: - s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x1f) << 8); + s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x0f) << 8); break; case 0xe94a: case 0xeaea: @@ -1586,10 +1612,11 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe94b: case 0xeaeb: - s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x1f) << 8); + s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x0f) << 8); break; case 0xed48: case 0xeee8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); @@ -1600,6 +1627,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed49: case 0xeee9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); @@ -1613,6 +1641,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed4a: case 0xeeea: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); else if (s3->bpp == 3) { @@ -1624,6 +1653,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed4b: case 0xeeeb: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); else if (s3->bpp == 3) { @@ -1977,29 +2007,39 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) break; case 0x8120: + addr = 0xa2e8; + break; case 0x8122: /*BKGD_COLOR*/ - WRITE8(addr, s3->accel.bkgd_color, val); - return; + addr = 0xa2ea; + break; case 0x8124: + addr = 0xa6e8; + break; case 0x8126: /*FRGD_COLOR*/ - WRITE8(addr, s3->accel.frgd_color, val); - return; + addr = 0xa6ea; + break; case 0x8128: + addr = 0xaae8; + break; case 0x812a: /*WRT_MASK*/ - WRITE8(addr, s3->accel.wrt_mask, val); - return; + addr = 0xaaea; + break; case 0x812c: + addr = 0xaee8; + break; case 0x812e: /*RD_MASK*/ - WRITE8(addr, s3->accel.rd_mask, val); - return; + addr = 0xaeea; + break; case 0x8130: + addr = 0xb2e8; + break; case 0x8132: /*COLOR_CMP*/ - WRITE8(addr, s3->accel.color_cmp, val); - return; + addr = 0xb2ea; + break; case 0x8134: addr = 0xb6e8; @@ -2056,9 +2096,11 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) break; case 0x8164: + addr = 0xe6e8; + break; case 0x8166: - WRITE8(addr, s3->accel.pat_bg_color, val); - return; + addr = 0xe6ea; + break; case 0x8168: addr = 0xeae8; @@ -2068,9 +2110,11 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) break; case 0x816c: + addr = 0xeee8; + break; case 0x816e: - WRITE8(addr, s3->accel.pat_fg_color, val); - return; + addr = 0xeeea; + break; default: break; @@ -2235,7 +2279,7 @@ s3_vblank_start(svga_t *svga) static uint32_t s3_hwcursor_convert_addr(svga_t *svga) { - if ((svga->bpp == 8) && (((svga->gdcreg[5] & 0x60) == 0x20) || (svga->crtc[0x3a] & 0x10)) && (svga->crtc[0x45] & 0x10)) { + if ((svga->bpp >= 8) && (((svga->gdcreg[5] & 0x60) == 0x20) || (svga->crtc[0x3a] & 0x10)) && (svga->crtc[0x45] & 0x10)) { if (svga->crtc[0x3a] & 0x10) return ((svga->hwcursor_latch.addr & 0xfffff1ff) | ((svga->hwcursor_latch.addr & 0x200) << 2)) | 0x600; else if ((svga->gdcreg[5] & 0x60) == 0x20) @@ -3019,27 +3063,38 @@ s3_out(uint16_t addr, uint8_t val, void *priv) else rs2 = (svga->crtc[0x55] & 0x01); // rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); - if (s3->chip >= S3_TRIO32) - svga_out(addr, val, svga); - else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { - rs3 = !!(svga->crtc[0x55] & 0x02); - bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) - ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) { - rs3 = !!(svga->crtc[0x55] & 0x02); - tvp3026_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && - ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805))) - att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if (s3->chip <= S3_86C924) { - sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); - } else if (s3->card_type == S3_NUMBER9_9FX_531) - att498_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) - sc1502x_ramdac_out(addr, val, svga->ramdac, svga); - else - sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); + switch (s3->ramdac_type) { + case BUILT_IN: + default: + svga_out(addr, val, svga); + break; + case SC1148X: + sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case SC1502X: + sc1502x_ramdac_out(addr, val, svga->ramdac, svga); + break; + case ATT49X: + att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case ATT498: + att498_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case BT48X: + rs3 = !!(svga->crtc[0x55] & 0x02); + bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + break; + case IBM_RGB: + ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case S3_SDAC: + sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case TVP3026: + rs3 = !!(svga->crtc[0x55] & 0x02); + tvp3026_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + break; + } return; case 0x3D4: @@ -3084,7 +3139,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x5c: if (s3->elsa_eeprom) nmc93cxx_eeprom_write(s3->eeprom, !!(val & 0x80), !!(val & 0x40), !!(val & 0x10)); - if (s3->card_type == S3_PHOENIX_VISION868 || s3->card_type == S3_PHOENIX_VISION968) { + if ((s3->card_type == S3_PHOENIX_VISION868) || (s3->card_type == S3_PHOENIX_VISION968)) { if ((val & 0x20) && (!(svga->crtc[0x55] & 0x01) && !(svga->crtc[0x43] & 2))) svga->dac_addr |= 0x20; } else if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968) { @@ -3136,6 +3191,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) if ((s3->chip == S3_VISION964) || (s3->chip == S3_VISION968)) break; svga->hwcursor.ena = val & 1; + s3_log("Write CRTC45=%02x.\n", val); break; case 0x46: case 0x47: @@ -3213,12 +3269,14 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x55: s3_log("[%04X:%08X]: Write CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]); if (s3->chip == S3_86C928) { - if (val & 0x28) { - svga->hwcursor_draw = NULL; - svga->dac_hwcursor_draw = bt48x_hwcursor_draw; - } else { - svga->hwcursor_draw = s3_hwcursor_draw; - svga->dac_hwcursor_draw = NULL; + if (s3->ramdac_type == BT48X) { + if (val & 0x28) { + svga->hwcursor_draw = NULL; + svga->dac_hwcursor_draw = bt48x_hwcursor_draw; + } else { + svga->hwcursor_draw = s3_hwcursor_draw; + svga->dac_hwcursor_draw = NULL; + } } } break; @@ -3345,32 +3403,43 @@ s3_in(uint16_t addr, void *priv) case 0x3c8: case 0x3c9: rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); - if (s3->chip >= S3_TRIO32) - return svga_in(addr, svga); - else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { - if (s3->chip == S3_86C928) - rs3 = !!(svga->crtc[0x55] & 0x28) || !!(svga->crtc[0x45] & 0x20) || !!(svga->crtc[0x55] & 0x02); /*Quite insane but Win95's S3 driver wants it set at all costs for 8bpp+ mode*/ - else + switch (s3->ramdac_type) { + case BUILT_IN: + default: + temp = svga_in(addr, svga); + break; + case SC1148X: + temp = sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case SC1502X: + temp = sc1502x_ramdac_in(addr, svga->ramdac, svga); + break; + case ATT49X: + temp = att49x_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case ATT498: + temp = att498_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case BT48X: + if (s3->chip == S3_86C928) + rs3 = !!(svga->crtc[0x55] & 0x28) || !!(svga->crtc[0x45] & 0x20) || !!(svga->crtc[0x55] & 0x02); /*Quite insane but Win95's S3 driver wants it set at all costs for 8bpp+ mode*/ + else + rs3 = !!(svga->crtc[0x55] & 0x02); + + temp = bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + break; + case IBM_RGB: + temp = ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case S3_SDAC: + temp = sdac_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case TVP3026: rs3 = !!(svga->crtc[0x55] & 0x02); - temp = bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - return temp; - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) - return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); - else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) { - rs3 = !!(svga->crtc[0x55] & 0x02); - return tvp3026_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && - ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805))) - return att49x_ramdac_in(addr, rs2, svga->ramdac, svga); - else if (s3->chip <= S3_86C924) - return sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); - else if (s3->card_type == S3_NUMBER9_9FX_531) - return att498_ramdac_in(addr, rs2, svga->ramdac, svga); - else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) - return sc1502x_ramdac_in(addr, svga->ramdac, svga); - else - return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); - break; + temp = tvp3026_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + break; + } + return temp; case 0x3d4: return svga->crtcreg; @@ -3650,20 +3719,21 @@ s3_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); - if ((s3->chip == S3_VISION964) || (s3->chip == S3_86C928)) { - if (s3->card_type == S3_ELSAWIN2KPROX_964) - ibm_rgb528_recalctimings(svga->ramdac, svga); - else { + switch (s3->ramdac_type) { + case BT48X: bt48x_recalctimings(svga->ramdac, svga); svga->interlace |= (!!(svga->crtc[0x42] & 0x20)); - } - } else if (s3->chip == S3_VISION968) { - if ((s3->card_type == S3_SPEA_MERCURY_P64V) || (s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) - tvp3026_recalctimings(svga->ramdac, svga); - else + break; + case IBM_RGB: ibm_rgb528_recalctimings(svga->ramdac, svga); - } else - svga->interlace = !!(svga->crtc[0x42] & 0x20); + break; + case TVP3026: + tvp3026_recalctimings(svga->ramdac, svga); + break; + default: + svga->interlace = !!(svga->crtc[0x42] & 0x20); + break; + } if (s3->chip >= S3_TRIO32) { switch (svga->crtc[0x67] >> 4) { @@ -3797,13 +3867,127 @@ s3_recalctimings(svga_t *svga) break; } break; - + case S3_ELSAWIN1K_86C928: + case S3_ELSAWIN2K_86C928: + switch (s3->width) { + case 1024: + switch (svga->hdisp) { + case 256: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 512: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 1280: /*Account for the 1280x1024 resolution*/ + switch (svga->hdisp) { + case 320: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 2048: /*Account for the 1280x1024 resolution and the ELSA EEPROM resolutions*/ + switch (svga->hdisp) { + case 320: + case 384: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 576: + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + if (s3->ramdac_type == BT48X) { + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + } + break; + } + break; + default: + break; + } + break; default: break; } break; case S3_86C928PCI: switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + switch (s3->width) { + case 1024: + switch (svga->hdisp) { + case 256: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 512: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 1280: /*Account for the 1280x1024 resolution*/ + switch (svga->hdisp) { + case 320: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 2048: /*Account for the 1280x1024 resolution and the ELSA EEPROM resolutions*/ + switch (svga->hdisp) { + case 320: + case 384: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 576: + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + case S3_SPEA_MERCURY_LITE_PCI: switch (s3->width) { case 640: @@ -3961,6 +4145,28 @@ s3_recalctimings(svga_t *svga) break; } break; + case S3_ELSAWIN1K_86C928: + case S3_ELSAWIN2K_86C928: + switch (s3->width) { + case 2048: + if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } else { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + break; + default: + if (s3->ramdac_type == BT48X) + svga->clock /= 2.0; + else if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } + break; + } + break; default: break; @@ -3968,6 +4174,10 @@ s3_recalctimings(svga_t *svga) break; case S3_86C928PCI: switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; case S3_SPEA_MERCURY_LITE_PCI: switch (s3->width) { case 640: @@ -4157,6 +4367,28 @@ s3_recalctimings(svga_t *svga) break; } break; + case S3_ELSAWIN1K_86C928: + case S3_ELSAWIN2K_86C928: + switch (s3->width) { + case 2048: + if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } else { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + break; + default: + if (s3->ramdac_type == BT48X) + svga->clock /= 2.0; + else if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } + break; + } + break; default: break; @@ -4164,6 +4396,10 @@ s3_recalctimings(svga_t *svga) break; case S3_86C928PCI: switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; case S3_SPEA_MERCURY_LITE_PCI: switch (s3->width) { case 640: @@ -4365,11 +4601,32 @@ s3_recalctimings(svga_t *svga) case 32: svga->render = svga_render_32bpp_highres; switch (s3->chip) { + case S3_86C928: + switch (s3->card_type) { + case S3_ELSAWIN1K_86C928: + svga->hdisp >>= 2; + svga->dots_per_clock >>= 2; + svga->clock *= 2.0; + break; + default: + break; + } + break; + case S3_86C928PCI: + switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + svga->hdisp >>= 2; + svga->dots_per_clock >>= 2; + svga->clock *= 2.0; + break; + default: + break; + } + break; case S3_VISION864: svga->hdisp >>= 2; svga->dots_per_clock >>= 2; break; - case S3_VISION868: switch (s3->card_type) { case S3_PHOENIX_VISION868: @@ -4499,7 +4756,8 @@ s3_recalctimings(svga_t *svga) } } - if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_VISION864) || (s3->chip == S3_VISION868) || (s3->chip == S3_VISION968)) + if ((((s3->card_type == S3_ELSAWIN1K_86C928) || (s3->card_type == S3_ELSAWIN1KPCI_86C928)) && (svga->bpp == 32)) || + (s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_VISION864) || (s3->chip == S3_VISION868) || (s3->chip == S3_VISION968)) svga->hoverride = 1; else svga->hoverride = 0; @@ -4768,12 +5026,13 @@ s3_updatemapping(s3_t *s3) if (s3->chip >= S3_86C928) { s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { + if (s3->chip <= S3_86C805) { if (s3->vlb) s3->linear_base &= 0x03ffffff; - else + else if (!s3->pci) s3->linear_base &= 0x00ffffff; } + if ((svga->crtc[0x58] & 0x10) || (s3->accel.advfunc_cntl & 0x10)) { /*Linear framebuffer*/ mem_mapping_disable(&svga->mapping); @@ -7599,6 +7858,7 @@ polygon_setup(s3_t *s3) old_dest_dat = dest_dat; \ ROPMIX_READ(dest_dat, pat_dat, src_dat); \ out = (out & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ + out &= 0xFFFFFF; \ } #define WRITE(addr, dat) \ @@ -8548,6 +8808,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->bpp == 0) && s3->color_16bit) { s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask; + s3_log("CMD2: RDMASK16CHECK=%d, rdmask=%04x.\n", s3->accel.rd_mask_16bit_check, rd_mask); if (s3->accel.rd_mask_16bit_check) { if (s3->accel.cmd == 0x41b3) { if (frgd_mix == 0) { @@ -8952,6 +9213,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->bpp == 0) && s3->color_16bit) { s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask; + s3_log("CMD6: RDMASK16CHECK=%d.\n", s3->accel.rd_mask_16bit_check); if (s3->accel.rd_mask_16bit_check) { if (!(clip_r & 0x400)) s3->accel.start = 1; @@ -9543,6 +9805,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; case 14: /*ROPBlt (Vision868/968 only)*/ + ; + uint32_t mono_pattern[64] = { 0 }; if (s3->chip != S3_VISION968 && s3->chip != S3_VISION868) break; @@ -9552,11 +9816,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi 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; s3->accel.cy = s3->accel.cur_y & 0xfff; @@ -9567,13 +9827,35 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.dest = dstbase + (s3->accel.dy * s3->width); s3->accel.src = srcbase + (s3->accel.cy * s3->width); s3->accel.pattern = (s3->accel.py * s3->width); + s3_log("ROPBLT=%04x, PIXCntl=%04x, Misc1=%04x, PATBKGDCOL=%08x, PATFRGDCOL=%08x, COLBKGDCOL=%08x, COLFRGDCOL=%08x, PX=%d, PY=%d, DX=%d, DY=%d, CX=%d, CY=%d, FRGDSEL=%x, BKGDSEL=%x, RDMASK=%08x, WRTMASK=%08x, ROPMIX=%03x, pitch=%d.\n", s3->accel.cmd, s3->accel.multifunc[0xa], s3->accel.multifunc[0xe], s3->accel.pat_bg_color, s3->accel.pat_fg_color, s3->accel.bkgd_color, s3->accel.frgd_color, s3->accel.px, s3->accel.py, s3->accel.dx, s3->accel.dy, s3->accel.cx, s3->accel.cy, frgd_mix, bkgd_mix, s3->accel.rd_mask, s3->accel.wrt_mask, s3->accel.ropmix, s3->width); } if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ + if (s3->accel.ropmix & 0x100) { + int x; + int y; + switch (s3->accel.cmd & 0x600) { + case 0x000: + case 0x600: + mix_dat &= 0xff; + break; + case 0x200: + mix_dat &= 0xffff; + break; + default: + break; + } + + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + mono_pattern[y * 8 + (7 - x)] = (mix_dat & (1 << (x + y * 8))) & 0x80000000; + } + } + } while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { + if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = s3->accel.bkgd_color; @@ -9592,24 +9874,18 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } - if (s3->accel.ropmix & 0x100) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + if (s3->accel.ropmix & 0x100) { /*Mono pattern used*/ + switch (mono_pattern[(s3->accel.py & 7) * 8 + (s3->accel.px & 7)] ? (frgd_mix & 1) : (bkgd_mix & 1)) { case 0: pat_dat = s3->accel.pat_bg_color; break; case 1: pat_dat = s3->accel.pat_fg_color; break; - case 2: - pat_dat = cpu_dat; - break; - case 3: - READ(s3->accel.pattern + s3->accel.px, pat_dat); - break; - default: break; } + s3_log("MonoMIX=%08x, PX=%d, PY=%d.\n", mix_dat, s3->accel.px & 7, s3->accel.py & 7); } else { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: @@ -9645,19 +9921,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } else update = 1; - if (s3->bpp == 2) { - src_dat &= 0xff; - pat_dat &= 0xff; - } else if (s3->bpp == 1) { - src_dat &= 0xffff; - pat_dat &= 0xffff; - } - if (update) { READ(s3->accel.dest + s3->accel.dx, dest_dat); ROPMIX + s3_log("Destination=%08x, Source=%08x, Pattern=%08x, OUT=%08x, mix=%08x, count=%d.\n", dest_dat, src_dat, pat_dat, out, mix_dat, count); if (s3->accel.cmd & 0x10) { WRITE(s3->accel.dest + s3->accel.dx, out); } @@ -9666,6 +9935,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi mix_dat <<= 1; mix_dat |= 1; + if (s3->bpp == 0) cpu_dat >>= 8; else @@ -9997,8 +10267,10 @@ s3_reset(void *priv) s3_t *s3 = (s3_t *) priv; if (reset_state != NULL) { - s3->accel.multifunc[0xe] &= ~(0x200 | 0x10); s3_disable_handlers(s3); + s3->accel.multifunc[0xd] = 0xd000; + s3->accel.multifunc[0xe] = 0xe000; + s3_log("S3 reset done.\n"); s3->force_busy = 0; s3->blitter_busy = 0; s3->fifo_read_idx = 0; @@ -10007,7 +10279,8 @@ s3_reset(void *priv) reset_state->pci_slot = s3->pci_slot; *s3 = *reset_state; - } + } else + s3_log("NULL reset.\n"); } static uint16_t @@ -10111,6 +10384,21 @@ s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); break; + case S3_ELSAWIN1K_86C928: + bios_fn = ROM_ELSAWIN1KVL_86C928; + chip = S3_86C928; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); + break; + case S3_ELSAWIN1KPCI_86C928: + bios_fn = ROM_ELSAWIN1KPCI_86C928; + chip = S3_86C928PCI; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c928pci); + break; + case S3_ELSAWIN2K_86C928: + bios_fn = ROM_ELSAWIN2K_86C928; + chip = S3_86C928; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); + break; case S3_SPEA_MERCURY_LITE_PCI: bios_fn = ROM_SPEA_MERCURY_LITE_PCI; chip = S3_86C928PCI; @@ -10482,6 +10770,7 @@ s3_init(const device_t *info) s3->accel_start = s3_accel_start; s3->elsa_eeprom = 0; + s3->ramdac_type = BUILT_IN; switch (s3->card_type) { case S3_ORCHID_86C911: @@ -10492,8 +10781,10 @@ s3_init(const device_t *info) s3->id_ext = stepping; s3->id_ext_pci = 0; s3->packed_mmio = 0; + s3->accel.rd_mask = 0xff; svga->ramdac = device_add(&sc11483_ramdac_device); + s3->ramdac_type = SC1148X; if (s3->card_type == S3_ORCHID_86C911) { svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; @@ -10501,6 +10792,7 @@ s3_init(const device_t *info) /* DCS2824-0 = Diamond ICD2061A-compatible. */ svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; + icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); } break; @@ -10511,8 +10803,10 @@ s3_init(const device_t *info) s3->id_ext = stepping; s3->id_ext_pci = 0; s3->packed_mmio = 0; + s3->accel.rd_mask = 0xff; svga->ramdac = device_add(&sc11483_ramdac_device); + s3->ramdac_type = SC1148X; svga->clock_gen = device_add(&ics2494an_305_device); svga->getclock = ics2494_getclock; break; @@ -10528,6 +10822,7 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&gendac_ramdac_device); + s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; break; @@ -10544,6 +10839,7 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&att491_ramdac_device); + s3->ramdac_type = ATT49X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; if (info->local == S3_WINNER1000_805) @@ -10560,6 +10856,7 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&att490_ramdac_device); + s3->ramdac_type = ATT49X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; @@ -10575,10 +10872,43 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&att492_ramdac_device); + s3->ramdac_type = ATT49X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; + case S3_ELSAWIN1K_86C928: + svga->decode_mask = (4 << 20) - 1; + stepping = 0x91; /*86C928D*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&sc1502x_ramdac_device); + s3->ramdac_type = SC1502X; + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + s3->elsa_eeprom = 1; + icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + break; + + case S3_ELSAWIN2K_86C928: + svga->decode_mask = (4 << 20) - 1; + stepping = 0x91; /*86C928D*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&bt485_ramdac_device); + s3->ramdac_type = BT48X; + svga->clock_gen = device_add(&ics9161_device); + svga->getclock = ics9161_getclock; + s3->elsa_eeprom = 1; + icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + break; + case S3_METHEUS_86C928: svga->decode_mask = (4 << 20) - 1; stepping = 0x91; /*86C928D*/ @@ -10588,10 +10918,27 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&bt485_ramdac_device); + s3->ramdac_type = BT48X; svga->clock_gen = device_add(&ics2494an_305_device); svga->getclock = ics2494_getclock; break; + case S3_ELSAWIN1KPCI_86C928: + svga->decode_mask = (4 << 20) - 1; + stepping = 0xb0; /*86C928PCI*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = stepping; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&sc1502x_ramdac_device); + s3->ramdac_type = SC1502X; + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + s3->elsa_eeprom = 1; + icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + break; + case S3_SPEA_MERCURY_LITE_PCI: svga->decode_mask = (4 << 20) - 1; stepping = 0xb0; /*86C928PCI*/ @@ -10601,6 +10948,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&sc1502x_ramdac_device); + s3->ramdac_type = SC1502X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; @@ -10619,6 +10967,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&sdac_ramdac_device); + s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; break; @@ -10636,6 +10985,7 @@ s3_init(const device_t *info) switch (info->local) { case S3_ELSAWIN2KPROX_964: svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + s3->ramdac_type = IBM_RGB; svga->clock_gen = svga->ramdac; svga->getclock = ibm_rgb528_getclock; s3->elsa_eeprom = 1; @@ -10643,8 +10993,10 @@ s3_init(const device_t *info) break; default: svga->ramdac = device_add(&bt485_ramdac_device); + s3->ramdac_type = BT48X; svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; + icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); break; } break; @@ -10678,6 +11030,7 @@ s3_init(const device_t *info) case S3_PHOENIX_VISION968: case S3_NUMBER9_9FX_771: svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + s3->ramdac_type = IBM_RGB; svga->clock_gen = svga->ramdac; svga->getclock = ibm_rgb528_getclock; if (info->local == S3_ELSAWIN2KPROX) { @@ -10690,6 +11043,7 @@ s3_init(const device_t *info) break; default: svga->ramdac = device_add(&tvp3026_ramdac_device); + s3->ramdac_type = TVP3026; svga->clock_gen = svga->ramdac; svga->getclock = tvp3026_getclock; svga->conv_16to32 = tvp3026_conv_16to32; @@ -10718,10 +11072,13 @@ s3_init(const device_t *info) if (info->local == S3_NUMBER9_9FX_531) { svga->ramdac = device_add(&att498_ramdac_device); + s3->ramdac_type = ATT498; svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; + icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); } else { svga->ramdac = device_add(&sdac_ramdac_device); + s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; } @@ -10808,6 +11165,24 @@ s3_init(const device_t *info) s3->eeprom_data[0x08] = 0x83d6; snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_805_%d.nvr", s3->eeprom_inst); break; + case S3_ELSAWIN1K_86C928: + s3->eeprom_data[0x02] = 0x0912; + s3->eeprom_data[0x07] = 0xa604; + s3->eeprom_data[0x08] = 0xa604; + snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_928_vlb_%d.nvr", s3->eeprom_inst); + break; + case S3_ELSAWIN1KPCI_86C928: + s3->eeprom_data[0x02] = 0x0914; + s3->eeprom_data[0x07] = 0xa604; + s3->eeprom_data[0x08] = 0xa604; + snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_928_pci_%d.nvr", s3->eeprom_inst); + break; + case S3_ELSAWIN2K_86C928: + s3->eeprom_data[0x02] = 0x0920; + s3->eeprom_data[0x07] = 0xa604; + s3->eeprom_data[0x08] = 0xa604; + snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_2k_928_isa_%d.nvr", s3->eeprom_inst); + break; case S3_ELSAWIN2KPROX: s3->eeprom_data[0x02] = 0x094a; s3->eeprom_data[0x07] = 0xf424; @@ -10910,6 +11285,24 @@ s3_mirocrystal_10sd_805_available(void) return rom_present(ROM_MIROCRYSTAL10SD_805); } +static int +s3_elsa_winner1000_86c928_vlb_available(void) +{ + return rom_present(ROM_ELSAWIN1KVL_86C928); +} + +static int +s3_elsa_winner1000_86c928_pci_available(void) +{ + return rom_present(ROM_ELSAWIN1KPCI_86C928); +} + +static int +s3_elsa_winner2000_86c928_available(void) +{ + return rom_present(ROM_ELSAWIN2K_86C928); +} + static int s3_metheus_86c928_available(void) { @@ -11350,7 +11743,7 @@ const device_t s3_spea_mirage_86c801_isa_device = { }; const device_t s3_winner1000_805_isa_device = { - .name = "S3 86c805 ISA (ELSA Winner 1000)", + .name = "S3 86c805 ISA (ELSA Winner 1000 805i)", .internal_name = "winner1000_805_isa", .flags = DEVICE_ISA16, .local = S3_WINNER1000_805, @@ -11447,6 +11840,34 @@ const device_t s3_phoenix_86c805_vlb_device = { .config = s3_9fx_config }; +const device_t s3_elsa_winner1000_86c928_vlb_device = { + .name = "S3 86c928 VLB (ELSA Winner 1000 928)", + .internal_name = "elsawin1k928_vlb", + .flags = DEVICE_VLB, + .local = S3_ELSAWIN1K_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + .available = s3_elsa_winner1000_86c928_vlb_available, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + +const device_t s3_elsa_winner2000_86c928_isa_device = { + .name = "S3 86c928 ISA (ELSA Winner 2000 928)", + .internal_name = "elsawin2k928_isa", + .flags = DEVICE_ISA16, + .local = S3_ELSAWIN2K_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + .available = s3_elsa_winner2000_86c928_available, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + const device_t s3_metheus_86c928_isa_device = { .name = "S3 86c928 ISA (Metheus Premier 928)", .internal_name = "metheus928_isa", @@ -11475,6 +11896,21 @@ const device_t s3_metheus_86c928_vlb_device = { .config = s3_standard_config }; +const device_t s3_elsa_winner1000_86c928_pci_device = { + .name = "S3 86c928 PCI (ELSA Winner 1000 928)", + .internal_name = "elsawin1k928_pci", + .flags = DEVICE_PCI, + .local = S3_ELSAWIN1KPCI_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + .available = s3_elsa_winner1000_86c928_pci_available, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + + const device_t s3_spea_mercury_lite_86c928_pci_device = { .name = "S3 86c928 PCI (SPEA Mercury Lite)", .internal_name = "spea_mercurylite_pci", diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 3bd6d694d..d8356df4a 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -828,6 +828,9 @@ s3_virge_recalctimings(svga_t *svga) svga->hdisp = svga->hdisp_old; + if (virge->chip >= S3_TRIO3D2X) { + svga_set_ramdac_type(svga, (svga->seqregs[0x1b] & 0x10) ? RAMDAC_8BIT : RAMDAC_6BIT); + } if (!svga->scrblank && svga->attr_palette_enable && (svga->crtc[0x43] & 0x80)) { /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 302a26f23..cbbf98ab4 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1480,6 +1480,7 @@ svga_poll(void *priv) svga->scanline = 0; if (svga->attrregs[0x10] & 0x20) { svga->scrollcache = 0; + svga->half_pixel = 0; svga->x_add = svga->left_overscan; } } @@ -1580,11 +1581,17 @@ svga_poll(void *priv) if (svga->scrollcache > 8) svga->scrollcache = 0; } + svga->half_pixel = 0; } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || - (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) + (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) { + svga->half_pixel = 0; svga->scrollcache &= 0x07; - else + } else { + if (svga->scrollcache > 7) + svga->scrollcache = 7; + svga->half_pixel = svga->scrollcache & 0x01; svga->scrollcache = (svga->scrollcache & 0x06) >> 1; + } if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) svga->scrollcache <<= 1; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index f43db41c4..92228243f 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -243,6 +243,8 @@ svga_render_text_80(svga_t *svga) p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; xinc = (svga->seqregs[1] & 1) ? 8 : 9; + static uint32_t col = 0x00000000; + for (int x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { if (!svga->force_old_addr) addr = svga->remap_func(svga, svga->memaddr) & svga->vram_display_mask; @@ -263,30 +265,71 @@ svga_render_text_80(svga_t *svga) charaddr = svga->charseta + (chr * 128); if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; - fg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; + bg = attr & 15; + fg = attr >> 4; } else { - fg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; - bg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; + fg = attr & 15; + bg = attr >> 4; if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7] & svga->dac_mask]; + bg = (attr >> 4) & 7; if (svga->blink & 16) fg = bg; } } dat = svga->vram[charaddr + (svga->scanline << 2)]; - if (svga->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + + if (svga->attrregs[0x10] & 0x40) { + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) { + uint32_t col16 = (dat & (0x80 >> xx)) ? fg : bg; + if ((x + xx - svga->scrollcache) & 1) { + col |= col16; + if ((x + xx - 1) >= 0) + p[xx - 1] = svga->pallook[col & svga->dac_mask]; + if ((x + xx) >= 0) + p[xx] = svga->pallook[col & svga->dac_mask]; + } else + col = col16 << 4; + } + } else { + for (xx = 0; xx < 9; xx++) { + uint32_t col16; + if (xx < 8) + col16 = (dat & (0x80 >> xx)) ? fg : bg; + else if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + col16 = bg; + else + col16 = (dat & 1) ? fg : bg; + if ((x + xx - svga->scrollcache) & 1) { + col |= col16; + if ((x + xx - 1) >= 0) + p[xx - 1] = svga->pallook[col & svga->dac_mask]; + if ((x + xx) >= 0) + p[xx] = svga->pallook[col & svga->dac_mask]; + } else + col = col16 << 4; + } + } } 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; + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) { + col = (col << 4) | ((dat & (0x80 >> xx)) ? fg : bg); + p[xx] = svga->pallook[svga->egapal[col & 0x0f] & svga->dac_mask]; + } + } else { + for (xx = 0; xx < 8; xx++) { + col = (col << 4) | ((dat & (0x80 >> xx)) ? fg : bg); + p[xx] = svga->pallook[svga->egapal[col & 0x0f] & svga->dac_mask]; + } + if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + col = (col << 4) | bg; + else + col = (col << 4) | ((dat & 1) ? fg : bg); + p[8] = svga->pallook[svga->egapal[col & 0x0f] & svga->dac_mask]; + } } + svga->memaddr += 4; p += xinc; } @@ -764,6 +807,8 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) uint32_t incr_counter = 0; uint32_t load_counter = 0; uint32_t edat = 0; + static uint32_t col = 0; + static uint32_t col2 = 0; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += charwidth) { if (load_counter == 0) { /* Find our address */ @@ -882,8 +927,21 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) } } else if (combine8bits) { if (svga->packed_4bpp) { - uint32_t p0 = svga->map8[c0 & svga->dac_mask]; - uint32_t p1 = svga->map8[c1 & svga->dac_mask]; + uint32_t p0; + uint32_t p1; + if (svga->half_pixel) { + col &= 0xf0; + col |= (c0 >> 4) & 0xff; + col2 = (c0 << 4) & 0xff; + col2 |= (c1 >> 4) & 0xff; + p0 = svga->map8[col & svga->dac_mask]; + p1 = svga->map8[col2 & svga->dac_mask]; + col = (c1 << 4) & 0xff; + } else { + p0 = svga->map8[c0 & svga->dac_mask]; + p1 = svga->map8[c1 & svga->dac_mask]; + col = p1; + } const int outoffs = i << dwshift; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; @@ -891,7 +949,16 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) p[outoffs + subx + dotwidth] = p1; } else { uint32_t ccombined = (c0 << 4) | c1; - uint32_t p0 = svga->map8[ccombined & svga->dac_mask]; + uint32_t p0; + if (svga->half_pixel) { + col &= 0xf0; + col |= (ccombined >> 4) & 0xff; + p0 = svga->map8[col & svga->dac_mask]; + col = (ccombined << 4) & 0xff; + } else { + p0 = svga->map8[ccombined & svga->dac_mask]; + col = p0; + } const int outoffs = (i >> 1) << dwshift; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; @@ -904,6 +971,11 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) p[outoffs + subx] = p0; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx + dotwidth] = p1; + if ((x + i - svga->scrollcache) & 0x01) + /* The lower 4 bits are undefined at this point. */ + col = c1 << 4; + else + col = (c0 << 4) | c1; } } diff --git a/src/video/vid_table.c b/src/video/vid_table.c index e2b9b3542..03e442e14 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -91,7 +91,6 @@ video_cards[] = { { .device = &nga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &nec_sv9000_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &ogc_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &jvga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &oti037c_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &oti067_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &oti077_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -127,10 +126,12 @@ video_cards[] = { { .device = &gd5434_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5434_diamond_speedstar_64_a3_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &inmos_isa_device, .flags = VIDEO_FLAG_TYPE_XGA }, + { .device = &jvga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &radius_svga_multiview_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_diamond_stealth_vram_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_orchid_86c911_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_ami_86c924_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner2000_86c928_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_metheus_86c928_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_phoenix_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_spea_mirage_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -160,6 +161,7 @@ video_cards[] = { { .device = &gd5430_diamond_speedstar_pro_se_a8_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5430_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5434_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner1000_86c928_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_metheus_86c928_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_mirocrystal_8s_805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_mirocrystal_10sd_805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -199,6 +201,7 @@ video_cards[] = { { .device = &et4000w32p_cardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000w32p_noncardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000w32p_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner1000_86c928_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_spea_mercury_lite_86c928_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_diamond_stealth64_964_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_elsa_winner2000_pro_x_964_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index a91a893df..8de29a2e6 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -3303,152 +3303,156 @@ xga_poll(void *priv) xga_log("XGA Poll=%d.\n", xga->on); if (xga->on) { - if (!xga->linepos) { - if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 32 : 0); - xga->hwcursor_oddeven = 0; - } - - if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 33 : 1); - xga->hwcursor_oddeven = 1; - } - - timer_advance_u64(&svga->timer, xga->dispofftime); - svga->cgastat |= 1; - xga->linepos = 1; - - if (xga->dispon) { - xga->h_disp_on = 1; - - xga->memaddr &= xga->vram_mask; - - if (xga->firstline == 2000) { - xga->firstline = xga->displine; - video_wait_for_buffer_monitor(svga->monitor_index); + if (svga->override) + svga_set_poll(svga); + else { + if (!xga->linepos) { + if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 32 : 0); + xga->hwcursor_oddeven = 0; } - if (xga->hwcursor_on) - xga->changedvram[xga->memaddr >> 12] = xga->changedvram[(xga->memaddr >> 12) + 1] = xga->interlace ? 3 : 2; + if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 33 : 1); + xga->hwcursor_oddeven = 1; + } - svga->render_xga(svga); + timer_advance_u64(&svga->timer, xga->dispofftime); + svga->cgastat |= 1; + xga->linepos = 1; - svga->x_add = svga->left_overscan; - xga_render_overscan_left(xga, svga); - xga_render_overscan_right(xga, svga); - svga->x_add = svga->left_overscan; + if (xga->dispon) { + xga->h_disp_on = 1; - if (xga->hwcursor_on) { - xga_hwcursor_draw(svga, xga->displine + svga->y_add); - xga->hwcursor_on--; - if (xga->hwcursor_on && xga->interlace) + xga->memaddr &= xga->vram_mask; + + if (xga->firstline == 2000) { + xga->firstline = xga->displine; + video_wait_for_buffer_monitor(svga->monitor_index); + } + + if (xga->hwcursor_on) + xga->changedvram[xga->memaddr >> 12] = xga->changedvram[(xga->memaddr >> 12) + 1] = xga->interlace ? 3 : 2; + + svga->render_xga(svga); + + svga->x_add = svga->left_overscan; + xga_render_overscan_left(xga, svga); + xga_render_overscan_right(xga, svga); + svga->x_add = svga->left_overscan; + + if (xga->hwcursor_on) { + xga_hwcursor_draw(svga, xga->displine + svga->y_add); xga->hwcursor_on--; + if (xga->hwcursor_on && xga->interlace) + xga->hwcursor_on--; + } + + if (xga->lastline < xga->displine) + xga->lastline = xga->displine; } - if (xga->lastline < xga->displine) - xga->lastline = xga->displine; - } - - xga->displine++; - if (xga->interlace) xga->displine++; - if ((svga->cgastat & 8) && ((xga->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) - svga->cgastat &= ~8; - if (xga->displine > 1500) - xga->displine = 0; - } else { - timer_advance_u64(&svga->timer, xga->dispontime); - if (xga->dispon) - svga->cgastat &= ~1; + if (xga->interlace) + xga->displine++; + if ((svga->cgastat & 8) && ((xga->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) + svga->cgastat &= ~8; + if (xga->displine > 1500) + xga->displine = 0; + } else { + timer_advance_u64(&svga->timer, xga->dispontime); + if (xga->dispon) + svga->cgastat &= ~1; - xga->h_disp_on = 0; + xga->h_disp_on = 0; - xga->linepos = 0; - if (xga->dispon) { - if (xga->scanline == xga->rowcount) { - xga->scanline = 0; + xga->linepos = 0; + if (xga->dispon) { + if (xga->scanline == xga->rowcount) { + xga->scanline = 0; - xga_log("MA=%08x, MALATCH=%x.\n", xga->memaddr, xga->memaddr_latch); - xga->memaddr_backup += (xga->rowoffset << 3); - if (xga->interlace) + xga_log("MA=%08x, MALATCH=%x.\n", xga->memaddr, xga->memaddr_latch); xga->memaddr_backup += (xga->rowoffset << 3); + if (xga->interlace) + xga->memaddr_backup += (xga->rowoffset << 3); - xga->memaddr_backup &= xga->vram_mask; - xga->memaddr = xga->memaddr_backup; - } else { - xga->scanline++; - xga->scanline &= 0x1f; - xga->memaddr = xga->memaddr_backup; + xga->memaddr_backup &= xga->vram_mask; + xga->memaddr = xga->memaddr_backup; + } else { + xga->scanline++; + xga->scanline &= 0x1f; + xga->memaddr = xga->memaddr_backup; + } } - } - xga->vc++; - xga->vc &= 0x7ff; + xga->vc++; + xga->vc &= 0x7ff; - if (xga->vc == xga->split) { - if (xga->interlace && xga->oddeven) - xga->memaddr = xga->memaddr_backup = (xga->rowoffset << 1); - else - xga->memaddr = xga->memaddr_backup = 0; + if (xga->vc == xga->split) { + if (xga->interlace && xga->oddeven) + xga->memaddr = xga->memaddr_backup = (xga->rowoffset << 1); + else + xga->memaddr = xga->memaddr_backup = 0; - xga->memaddr = (xga->memaddr << 2); - xga->memaddr_backup = (xga->memaddr_backup << 2); + xga->memaddr = (xga->memaddr << 2); + xga->memaddr_backup = (xga->memaddr_backup << 2); - xga->scanline = 0; - } - if (xga->vc == xga->dispend) { - xga->dispon = 0; - - for (x = 0; x < ((xga->vram_mask + 1) >> 12); x++) { - if (xga->changedvram[x]) - xga->changedvram[x]--; + xga->scanline = 0; } - if (svga->fullchange) - svga->fullchange--; - } - if (xga->vc == xga->v_syncstart) { - xga->dispon = 0; - svga->cgastat |= 8; - x = xga->h_disp; + if (xga->vc == xga->dispend) { + xga->dispon = 0; - if (xga->interlace && !xga->oddeven) - xga->lastline++; - if (xga->interlace && xga->oddeven) - xga->firstline--; + for (x = 0; x < ((xga->vram_mask + 1) >> 12); x++) { + if (xga->changedvram[x]) + xga->changedvram[x]--; + } + if (svga->fullchange) + svga->fullchange--; + } + if (xga->vc == xga->v_syncstart) { + xga->dispon = 0; + svga->cgastat |= 8; + x = xga->h_disp; - wx = x; + if (xga->interlace && !xga->oddeven) + xga->lastline++; + if (xga->interlace && xga->oddeven) + xga->firstline--; - wy = xga->lastline - xga->firstline; - svga_doblit(wx, wy, svga); + wx = x; - xga->firstline = 2000; - xga->lastline = 0; + wy = xga->lastline - xga->firstline; + svga_doblit(wx, wy, svga); - xga->firstline_draw = 2000; - xga->lastline_draw = 0; + xga->firstline = 2000; + xga->lastline = 0; - xga->oddeven ^= 1; + xga->firstline_draw = 2000; + xga->lastline_draw = 0; - svga->monitor->mon_changeframecount = xga->interlace ? 3 : 2; + xga->oddeven ^= 1; - if (xga->interlace && xga->oddeven) - xga->memaddr = xga->memaddr_backup = xga->memaddr_latch + (xga->rowoffset << 1); - else - xga->memaddr = xga->memaddr_backup = xga->memaddr_latch; + svga->monitor->mon_changeframecount = xga->interlace ? 3 : 2; - xga->memaddr = (xga->memaddr << 2); - xga->memaddr_backup = (xga->memaddr_backup << 2); - } - if (xga->vc == xga->v_total) { - xga->vc = 0; - xga->scanline = 0; - xga->dispon = 1; - xga->displine = (xga->interlace && xga->oddeven) ? 1 : 0; + if (xga->interlace && xga->oddeven) + xga->memaddr = xga->memaddr_backup = xga->memaddr_latch + (xga->rowoffset << 1); + else + xga->memaddr = xga->memaddr_backup = xga->memaddr_latch; - svga->x_add = svga->left_overscan; + xga->memaddr = (xga->memaddr << 2); + xga->memaddr_backup = (xga->memaddr_backup << 2); + } + if (xga->vc == xga->v_total) { + xga->vc = 0; + xga->scanline = 0; + xga->dispon = 1; + xga->displine = (xga->interlace && xga->oddeven) ? 1 : 0; - xga->hwcursor_on = 0; - xga->hwcursor_latch = xga->hwcursor; + svga->x_add = svga->left_overscan; + + xga->hwcursor_on = 0; + xga->hwcursor_latch = xga->hwcursor; + } } } } else